TERADATA case when statement in WHERE clause - teradata

I need to write a case statement in the WHERE clause, which is -
when current_date is 1st of Month then select data BETWEEN 1st day of prev month AND last day prev month
ELSE FROM 1st of Curr month till date. I have written this so far but it is not working. '05/01/2017' will be input date.
SELECT *
FROM MyTable
WHERE calendar_date
BETWEEN
CASE WHEN extract (day from CAST( '05/01/2017' AS DATE FORMAT 'MM/DD/YYYY')) =1 --check to see date is 1st of month
THEN ADD_MONTHS((CAST( '05/01/2017' AS DATE FORMAT 'MM/DD/YYYY') - EXTRACT(DAY FROM CAST( '05/01/2017' AS DATE FORMAT 'MM/DD/YYYY'))+1), -1) --1st of prev month
AND ADD_MONTHS(CURRENT_DATE - EXTRACT(DAY FROM CURRENT_date), 0 ) --last day prev month
ELSE CAST( '05/01/2017' AS DATE FORMAT 'MM/DD/YYYY') - EXTRACT(DAY FROM CAST( '05/01/2017' AS DATE FORMAT 'MM/DD/YYYY'))+1, 0) --else 1st of Curr mont
AND CURRENT_DATE
end
order by calendar_date

select *
from mytable
where calendar_date between case
when td_day_of_month (current_date) = 1
then current_date - interval '1' month
else td_month_begin (current_date)
end
and case
when td_day_of_month (current_date) = 1
then current_date - 1
else current_date
end
order by calendar_date

#Dudu, based on your suggestion, I was able to solve the sql. here it is:
SELECT * FROM MYTABLE
WHERE CALENDAR_DATE
BETWEEN
CASE WHEN extract (day from CAST( '05/15/2017' AS DATE FORMAT 'MM/DD/YYYY')) = 1
THEN (ADD_MONTHS((CAST( '05/15/2017' AS DATE FORMAT 'MM/DD/YYYY') - EXTRACT(DAY FROM CAST( '05/15/2017' AS DATE FORMAT 'MM/DD/YYYY'))+1), -1) )
ELSE ADD_MONTHS(CURRENT_DATE - EXTRACT(DAY FROM CURRENT_DATE)+1, 0)
END
AND
CASE WHEN extract (day from CAST( '05/15/2017' AS DATE FORMAT 'MM/DD/YYYY')) > 1
THEN CURRENT_DATE
ELSE ADD_MONTHS(CURRENT_DATE - EXTRACT(DAY FROM CURRENT_date), 0 )
END
AND REPORTNAME_MASTER_ID IN (2565,5216,5364)
order by CALENDAR_DATE

Related

How to compare a 7-month forward-looking data crossing 2022 and 2023 with 2019?

I have below the code:
SELECT T.postdate_debug AS POSTDATE,
(CAST(T.DEPART_DATE AS DATE FORMAT 'MM') (char(2))) AS "Month",
SUM(CASE WHEN T.dpt_date_yr_debug IN ('2019') THEN T.tot_REV ELSE 0 END) AS PY_REVENUE_THIS_WEEK,
SUM(CASE WHEN T.dpt_date_yr_debug IN (EXTRACT(YEAR FROM CURRENT_DATE)-1, EXTRACT(YEAR FROM CURRENT_DATE)) AND T.postdate_debug = CURRENT_DATE - TD_DAY_OF_WEEK(CURRENT_DATE)+1 THEN T.tot_REV ELSE 0 END) AS CY_REVENUE_THIS_WEEK,
SUM(CASE WHEN T.dpt_date_yr_debug IN (EXTRACT(YEAR FROM CURRENT_DATE)-1, EXTRACT(YEAR FROM CURRENT_DATE)) AND T.postdate_debug = CURRENT_DATE - TD_DAY_OF_WEEK(CURRENT_DATE)-6 THEN T.tot_REV ELSE 0 END) AS CY_REVENUE_LAST_WEEK,
SUM(CASE WHEN T.dpt_date_yr_debug IN (EXTRACT(YEAR FROM CURRENT_DATE)-1, EXTRACT(YEAR FROM CURRENT_DATE)) AND T.postdate_debug = CURRENT_DATE - TD_DAY_OF_WEEK(CURRENT_DATE)-13 THEN T.tot_REV ELSE 0 END) AS CY_REVENUE_TWO_WEEKS
FROM T
WHERE
(
(
(T.DEPART_DATE BETWEEN ADD_MONTHS(CURRENT_DATE - EXTRACT(DAY FROM CURRENT_DATE)+1, 0) AND ADD_MONTHS(CURRENT_DATE - EXTRACT(DAY FROM CURRENT_DATE)+1, +7) -1)
AND (T.postdate_debug=CURRENT_DATE - TD_DAY_OF_WEEK(CURRENT_DATE)+1 OR T.postdate_debug=CURRENT_DATE - TD_DAY_OF_WEEK(CURRENT_DATE)-6 OR T.postdate_debug=CURRENT_DATE - TD_DAY_OF_WEEK(CURRENT_DATE)-13)
)
OR
(
(T.DEPART_DATE BETWEEN ADD_MONTHS(CURRENT_DATE - EXTRACT(DAY FROM CURRENT_DATE)+1, -36) AND ADD_MONTHS(CURRENT_DATE - EXTRACT(DAY FROM CURRENT_DATE)+1, +7-36) -1)
AND T.postdate_debug=CURRENT_DATE - TD_DAY_OF_WEEK(CURRENT_DATE)-1095
)
)
And the outcome is:
enter image description here
My question is: when moving to next month, the 7-month forward-looking will be 7,8,9,10,11,12,1, and I would like the month of 1 data still compare with 2019-1. Any suggestion how to achieve this?

Teradata SQL - how to get data between current month and current month+8 (current month+8 will fall into 2023)

I have this code but returns 0 row:
SELECT
EXTRACT(MONTH FROM POST_DATE)
FROM
MY_TABLE
WHERE
EXTRACT(MONTH FROM POST_DATE) BETWEEN EXTRACT(MONTH FROM CURRENT_DATE) AND EXTRACT(MONTH FROM ADD_MONTHS(CURRENT_DATE,8))
Now it's month 5, and if my code changes to 7 instead 8, the result is showing 5,6,7,8,9,10,11,12.
And MY_TABLE has data for 2023.
Can anyone please help? Thanks.
Here we calculate the first day of this month, then we add 9 months to the last day of last month.
SELECT
EXTRACT(MONTH FROM POST_DATE)
FROM
MY_TABLE
WHERE POST_DATE BETWEEN
ADD_MONTHS(CURRENT_DATE - EXTRACT(DAY FROM CURRENT_DATE)+1, 0)
AND
ADD_MONTHS(CURRENT_DATE - EXTRACT(DAY FROM CURRENT_DATE), 9)
;

how to get the last weekday of the month in sqllite

given a date in sqllite I would like to find the last weekday of the month.
for example, if given 11/17/2021 then the last weekday of the month is 11/30. however, if given 4/30/2022 which falls on a saturday then the last weekday of the month is 4/29/2022.
i try the following but this only gives me the last day of the month which can be either a weekend of weeday.
SELECT date('now','start of month','+1 month','-1 day');
i am looking for the last weekday of the month given a specific date in sql lite.
can someone help me figure this out? thanks in advance
One solution is to calculate the day of the week for the end of the month, and adjust the result based off that value:
SELECT
CASE strftime('%w', date('now', 'start of month','+1 month','-1 day'))
WHEN '0' THEN date('now', 'start of month','+1 month','-3 day')
WHEN '6' THEN date('now', 'start of month','+1 month','-2 day')
ELSE date('now', 'start of month','+1 month','-1 day')
END;
The following will take a US formatted date (m/d/y) and output the last weekday in the month in the same US format:-
WITH
cte_inputdate AS (SELECT '12/19/2022' /*<<<<<<<<<<< change as required */ AS inputdate),
cte_convertdate AS
(SELECT
CASE
/* m/d/yyyy */
WHEN substr(inputdate,2,1) = '/'
AND substr(inputdate,4,1) = '/'
THEN substr(inputdate,5,4)||'-0'||substr(inputdate,1,1)||'-0'||substr(inputdate,3,1)
/* m/dd/yyyy */
WHEN substr(inputdate,2,1) = '/'
AND substr(inputdate,5,1) = '/'
THEN substr(inputdate,6,4)||'-0'||substr(inputdate,1,1)||'-'||substr(inputdate,3,2)
/* mm/d/yyyy */
WHEN substr(inputdate,3,1) = '/'
AND substr(inputdate,5,1) = '/'
THEN substr(inputdate,6,4)||'-'||substr(inputdate,1,2)||'-0'||substr(inputdate,4,1)
/* mm/dd/yyyy */
ELSE substr(inputdate,7,4)||'-'||substr(inputdate,1,2)||'-'||substr(inputdate,4,2)
END AS inputdate
FROM cte_inputdate
),
cte_lastweekdayofmonth AS
(SELECT *,
CASE CAST(strftime('%w',inputdate,'start of month','+1 month','-1 day') AS INTEGER)
WHEN 0 THEN date(inputdate,'start of month','+1 month','-3 day')
WHEN 6 THEN date(inputdate,'start of month','+1 month','-2 day')
ELSE date(inputdate,'start of month','+1 month','-1 day')
END AS lastweekdayofmonth
FROM cte_convertdate
)
/* Extract lastweekdayofthemonth converting it to m/d/yyyy format */
SELECT
CASE WHEN substr(lastweekdayofmonth,6,1) = '0' THEN substr(lastweekdayofmonth,7,1) ELSE substr(lastweekdayofmonth,6,2) END||'/'||
CASE WHEN substr(lastweekdayofmonth,9,1) = '0' THEN substr(lastweekdayofmonth,10,1) ELSE substr(lastweekdayofmonth,9,2) END||'/'||
substr(lastweekdayofmonth,1,4) AS lastweekdayofmonth
FROM cte_lastweekdayofmonth
;
e.g
for 11/17/2021 then :-
for 4/30/2022 then :-

How to calculate previous month data on starting of next month in Teradata

I am using condition below to show data for current month only/previous month(if its new month started).
let's say today is 3rd june so it should only give 1st an 2nd data,if its 10 it should give data from 1 to 9th,similarly it should be like this until month end but when there will be 1st of next month it should give data from previous month. the conditions I am using are giving blank data on every 1st. . Here is the condition I am using:
where Datestarted between CURRENT_DATE - EXTRACT( DAY FROM CURRENT_DATE) + 1
AND
ADD_MONTHS(( CURRENT_DATE - EXTRACT (DAY FROM CURRENT_DATE) + 1), 1) - 1
You probably need to base your calculation on yesterday, not today:
where Datestarted between (CURRENT_DATE-1) - EXTRACT( DAY FROM CURRENT_DATE-1) + 1
AND
CURRENT_DATE-1
Do you maybe mean previous month to date?
Try this:
select
calendar_date
from
sys_calendar.calendar
where
calendar_date between cast((ADD_MONTHS(CURRENT_DATE,-1)/100*100)+1 as DATE) and
add_months(current_date,-1)-1
EDIT: Based on your comments, let's try this:
SELECT
calendar_date
FROM
sys_calendar.CALENDAR
WHERE
(EXTRACT(DAY FROM CURRENT_DATE) = 1 --previous month
AND
Calendar_Date BETWEEN CAST((ADD_MONTHS(CURRENT_DATE, - 1)/100 * 100) + 1 AS DATE)
AND CURRENT_DATE - EXTRACT(DAY FROM CURRENT_DATE))
OR--current mtd
(
Calendar_Date BETWEEN CAST((CURRENT_DATE / 100 * 100) + 1 AS DATE)
AND CURRENT_DATE - 1
)
ORDER BY calendar_date

Calculate Average for the month in SQlite

I have an Sqlite table as below called balance history:
Table Balance History
Date Amount
2013-11-01 16:26:52 1000
2013-11-15 13:20:52 2000
2013-11-27 12:26:55 3000
I would like to calculate the average for the month.
**
The Expected OutPut will be 1666.67
**
Which will be (1000 * 14 days + 2000 * 12 days + 3000 * 4 days)/30 days
= (14000 + 24000 + 12000)/30 = 1666.67
How can I achieve this in SQlite? any help will be appreciated.
thanks
First, we have to compute the start and the end of each interval.
The simple query (SELECT Date AS "From", Amount FROM BalanceHistory WHERE Date GLOB '2013-11*') gets the start for each interval in the month.
(GLOB is case sensitive and thus allows to use a normal index; LIKE would require a special case-insensitive index.)
If there is no record for the first day of the month, the part after the UNION ALL adds the last record of the previous month and changes the day to the 1st.
The COALESCE computes the end of the interval.
The subquery gets the next date from the table, if there is one in the current month.
If there is no such record, it takes the first day of the next month:
SELECT date("From") AS "From",
COALESCE((SELECT date(MIN(Date))
FROM BalanceHistory
WHERE Date > "From"
AND Date GLOB '2013-11*'),
date('2013-11-01', '+1 month')
) AS "To",
"Amount"
FROM (SELECT Date AS "From",
Amount
FROM BalanceHistory
WHERE Date GLOB '2013-11*'
UNION ALL
SELECT *
FROM (SELECT date(Date, '+1 month', 'start of month'),
Amount
FROM BalanceHistory
WHERE Date < '2013-11'
AND NOT EXISTS (SELECT 1
FROM BalanceHistory
WHERE Date GLOB '2013-11-01*')
ORDER BY Date DESC
LIMIT 1)
);
From To Amount
---------- ---------- ------
2013-11-01 2013-11-15 1000
2013-11-15 2013-11-27 2000
2013-11-27 2013-12-01 3000
We can then wrap this in another query to compute the number of days, and add them up.
The strftime calculates the last day of the month, i.e., the number of days:
SELECT SUM((julianday("To") - julianday("From")) * Amount) /
strftime('%d', '2013-11-01', '+1 month', '-1 day') AS MonthAvg
FROM (SELECT date("From") AS "From",
COALESCE((SELECT date(MIN(Date))
FROM BalanceHistory
WHERE Date > "From"
AND Date GLOB '2013-11*'),
date('2013-11-01', '+1 month')
) AS "To",
"Amount"
FROM (SELECT Date AS "From",
Amount
FROM BalanceHistory
WHERE Date GLOB '2013-11*'
UNION ALL
SELECT *
FROM (SELECT date(Date, '+1 month', 'start of month'),
Amount
FROM BalanceHistory
WHERE Date < '2013-11'
AND NOT EXISTS (SELECT 1
FROM BalanceHistory
WHERE Date GLOB '2013-11-01*')
ORDER BY Date DESC
LIMIT 1)
)
)
And while we're at it, we can wrap this in yet another query to replace all those 2013-11 strings with the month as read from the table.
This allows as to compute this for every month:
SELECT Month,
(SELECT SUM((julianday("To") - julianday("From")) * Amount) /
strftime('%d', Month || '-01', '+1 month', '-1 day')
FROM (SELECT date("From") AS "From",
COALESCE((SELECT date(MIN(Date))
FROM BalanceHistory
WHERE Date > "From"
AND Date GLOB Month || '*'),
date(Month || '-01', '+1 month')
) AS "To",
"Amount"
FROM (SELECT Date AS "From",
Amount
FROM BalanceHistory
WHERE Date GLOB Month || '*'
UNION ALL
SELECT *
FROM (SELECT date(Date, '+1 month', 'start of month'),
Amount
FROM BalanceHistory
WHERE Date < Month
AND NOT EXISTS (SELECT 1
FROM BalanceHistory
WHERE Date GLOB Month || '-01*')
ORDER BY Date DESC
LIMIT 1)
)
)
) AS MonthAvg
FROM (SELECT DISTINCT strftime('%Y-%m', Date) AS Month
FROM BalanceHistory)
ORDER BY 1

Resources