CASE WHEN in WHERE clause to filter the dates - teradata-sql-assistant

I'm super junior in SQL and trying to automate my date parameters in below the codes in Teradata:
SELECT
POST_DATE_YR,
POST_DATE_MN,
SERV_NAME,
MARKET_NAME,
COUNTRY_NAME
FROM
MY_TABLE
WHERE
CASE WHEN (EXTRACT(MONTH FROM CURRENT_DATE)+6)<=12
THEN (POST_DATE_YR = '2022' AND POST_DATE_MN Between EXTRACT(MONTH FROM CURRENT_DATE) AND EXTRACT(MONTH FROM CURRENT_DATE)+6 )
ELSE
(POST_DATE_YR = '2022' AND POST_DATE_MN Between EXTRACT(MONTH FROM CURRENT_DATE) AND 12 )
or
(POST_DATE_YR = '2023' AND POST_DATE_MN Between 1 and EXTRACT(MONTH FROM CURRENT_DATE)-6 )
END
ORDER BY 1,2,3,4,5
What I'm trying to define is:
If current_month+6 <=12, then define date parameters as year=2022 and month between current_month and current_month+6.
If current_month+6 >12, then define date parameters as year=2022 and month between current_month and 12 PLUS year=2023 and month between 1 and current_month-6
It would be always 7-month data.
But I got error when executing. Can someone please help on how to achieve this? Thanks.

The CASE expression returns a value; the WHERE clause requires one or more predicates (conditions), not values.
SELECT
POST_DATE_YR,
POST_DATE_MN,
SERV_NAME,
MARKET_NAME,
COUNTRY_NAME
FROM
MY_TABLE
WHERE
(
EXTRACT(MONTH FROM CURRENT_DATE)+6)<=12
AND POST_DATE_YR = '2022'
AND POST_DATE_MN Between EXTRACT(MONTH FROM CURRENT_DATE)
AND EXTRACT(MONTH FROM CURRENT_DATE)
)
OR
(
POST_DATE_YR = '2022'
AND POST_DATE_MN Between EXTRACT(MONTH FROM CURRENT_DATE) AND 12
)
OR
(
POST_DATE_YR = '2023'
AND POST_DATE_MN Between 1 and EXTRACT(MONTH FROM CURRENT_DATE)-6
)
ORDER BY 1,2,3,4,5

Related

ANSI SQL grouping by (Indian) financial year YTD - (last 5 years YTD)

Can anyone kindly point out how to group data until today (for last 5 years) for Indian fiscal (Apr-Mar). Say for example I need to extract 'field1','field2' from table 'aaa' from 01-Apr to today date for the last 5 years. My current solution can work safe until Dec, but later will run into error
SELECT
"Date",
"Daily data",
"ID",
"GA%",
"MA%"
FROM "table"
WHERE month("Date") >= 4
AND month("Date") <= month(today())
AND date("Date") < date(today())
Expected result format grouped by fiscal years:
FY-1 sum(daily data during the period) sum(GA) sum(MA)
FY-2 sum(daily data during the period) sum(GA) sum(MA)
SELECT
"Date",
"Daily data",
"ID",
"GA%",
"MA%"
FROM "table"
WHERE
"Date" between '2021-04-01' and '2021-11-29'
OR
"Date" between '2020-04-01' and '2020-11-29'
OR
"Date" between '2019-04-01' and '2019-11-29'
OR
"Date" between '2018-04-01' and '2018-11-29'
OR
"Date" between '2017-04-01' and '2017-11-29'
untested notepad scribble
SELECT
MIN(`Date`) AS StartDate
, MAX(`Date`) AS EndDate
, COUNT(ID) AS CountId
, SUM(`GA%`) AS `TotalGa%`
, SUM(`MA%`) AS `TotalMa%`
FROM `table` AS aaa
WHERE
(
(YEAR(`Date`) BETWEEN YEAR(CURRENT_DATE) - 4 AND YEAR(CURRENT_DATE) - 1)
OR
(YEAR(`Date`) = YEAR(CURRENT_DATE) AND MONTH(`Date`) <= 11)
OR
(YEAR(`Date`) = YEAR(CURRENT_DATE) - 5 AND MONTH(`Date`) > 3)
)
AND
(
MONTH(`Date`) NOT IN (12, 1, 2, 3)
OR
YEAR(`Date`) = YEAR(CURRENT_DATE)
)
GROUP BY CASE WHEN MONTH(`Date`) <= 3 THEN YEAR(`Date`) - 1
ELSE YEAR(`Date`) END
ORDER BY MIN(`Date`) DESC

Return Monthly Data From Query Even When Month Does Not Exist In DataSet

I am a MS SQL Server guy, but am having to write some MySQL Queries. I am attempting to write a query that will show monthly sales data for a selected employee and if the employee has no sales data for that month show the month and a 0.
This is the query I have but it's returning NULL?
CREATE TABLE `saleamountbyemployee` (
`month_year` varchar(9) DEFAULT NULL,
`total_sales` int(11) NOT NULL,
`employee` char(17) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `saleamountbyemployee` (`month_year`,`total_sales`,`employee`) VALUES ('Feb 18','34512','James Jones');
INSERT INTO `saleamountbyemployee` (`month_year`,`total_sales`,`employee`) VALUES ('Feb 18','223','Sally Smith');
INSERT INTO `saleamountbyemployee` (`month_year`,`total_sales`,`employee`) VALUES ('Feb 18','22','James Jones');
WITH RECURSIVE
cte_months_to_pull AS (
SELECT DATE_FORMAT(#start_date, '%Y-%m-01') - INTERVAL #number_of_months MONTH AS month_to_pull
UNION ALL
SELECT month_to_pull + INTERVAL 1 MONTH
FROM cte_months_to_pull
WHERE month_to_pull < #start_date + INTERVAL #number_of_months - 2 MONTH
)
SELECT YRS.months_to_pull,T.employee,COALESCE(T.IA, 0) IA
FROM (SELECT DATE_Format(month_to_pull, '%b-%Y') months_to_pull
FROM cte_months_to_pull
ORDER BY months_to_pull
) AS YRS
LEFT JOIN (SELECT Date_format(month_year, '%b-%Y') AS `Month`
,employee,Sum(total_sales) AS IA
FROM saleamountbyemployee
WHERE employee = 'James Jones'
GROUP BY Date_format(month_year, '%b-%Y'), employee) T
ON YRS.months_to_pull = T.`Month`
order by month(STR_TO_DATE(CONCAT('01-',months_to_pull), '%d-%b-%Y')),YEAR(STR_TO_DATE(CONCAT('01-',months_to_pull), '%d-%b-%Y'))
EDIT
If I alter syntax to this:
SET #start_date = 'Jan 18';
SET #number_of_months = 12;
WITH RECURSIVE
cte_months_to_pull AS (
SELECT str_to_date(CONCAT(#start_date,' 01'), '%b %y %d') - INTERVAL #number_of_months MONTH AS month_to_pull
UNION ALL
SELECT month_to_pull + INTERVAL 1 MONTH
FROM cte_months_to_pull
WHERE month_to_pull < #start_date + INTERVAL #number_of_months - 2 MONTH
)
SELECT YRS.months_to_pull,T.employee,COALESCE(T.IA, 0) IA
FROM (SELECT DATE_Format(month_to_pull, '%b-%Y') months_to_pull
FROM cte_months_to_pull
ORDER BY months_to_pull
) AS YRS
LEFT JOIN (SELECT Date_format(month_year, '%b-%Y') AS `Month`
,employee,Sum(total_sales) AS IA
FROM saleamountbyemployee
WHERE employee = 'James Jones'
GROUP BY Date_format(month_year, '%b-%Y'), employee) T
ON YRS.months_to_pull = T.`Month`
order by month(STR_TO_DATE(CONCAT('01-',months_to_pull), '%d-%b-%Y')),YEAR(STR_TO_DATE(CONCAT('01-',months_to_pull), '%d-%b-%Y'))
I now get this error message:
Error Code: 1292. Incorrect datetime value: 'Jan 18'
This line in the CTE:
SELECT DATE_FORMAT(#start_date, '%Y-%m-01') - INTERVAL #number_of_months MONTH AS month_to_pull
The date format of '%Y-%m-01' doesn't match what's in the table. If you use 'Feb 18' as the value of the #start_date parameter, it will return NULL. The date_format you specified expects it to look like this:
SELECT DATE_FORMAT('2018-01-01', '%Y-%m-01') - INTERVAL 1 MONTH AS month_to_pull
Add ' 01' to the date, this will make it think it's the first of the month.
SELECT str_to_date(CONCAT(#start_date,' 01'), '%b %y %d') - INTERVAL #number_of_months MONTH AS month_to_pull
This will return the following if you use 'Feb 18' as the #start_date and 1 as the #number_of_months:
1/1/2018 12:00:00 AM
That VARCHAR data type and date format in the table is gonna bite you.
I am attempting to write a query that will show monthly sales data for a selected employee and if the employee has no sales data for that month show the month and a 0.
Assuming that you have data for some employee in each month, you can use conditional aggregation:
select month_year,
sum(case when employee = 'James Jones' then total_sales else 0 end) as monthly_sales
from saleamountbyemployee sae
group by month_year;

Retrieve data for specific months

MySQL Query is like this
SELECT MONTHNAME(access_date) as date,
DATE_FORMAT( access_date, '%m/%Y' ) as month_date ,
COUNT( log_id ) as total_count
FROM user_activity_log
WHERE dam_id = (
SELECT dam_id
FROM dam_content_details
WHERE content_type= '$content_type'
)
AND access_date >= last_day(NOW() - INTERVAL ($month) MONTH)
GROUP BY MONTH( access_date )
ORDER BY access_date ASC
i will pass the numbers like 1,2,3.... then its giving value for that month.
The problem i faced is it retrieving the data per 30 days,60 days like that. I want if i will write $month = '1; then it should return the current month data & previous month data starting from day 1.
My sample output - $month = 2
date month_date total_count
--------- ------------ -----------
December 12/2013 4
January 01/2014 1
I want for december it should calculate from 12/01/2013. 1st December 2013. Any idea how to solve it ?
You just have to remove = from >=.
Try this:
SELECT MONTHNAME(access_date) as date,
DATE_FORMAT( access_date, '%m/%Y' ) as month_date ,
COUNT( log_id ) as total_count
FROM user_activity_log
WHERE dam_id = (SELECT dam_id FROM dam_content_details WHERE content_type= '$content_type') AND
access_date > LAST_DAY(NOW() - INTERVAL (($month)+1) MONTH)
GROUP BY MONTH( access_date )
ORDER BY access_date ASC

Same month two different SUMS

I'm trying to get different Sums for same month on same Year, just to get sums by different types. Tried using this code:
SELECT a.invoice_type, year( a.date ) AS Year,
date_format( a.date, '%M' ) AS `month` ,
Sum( x.amount * x.price ) AS sum FROM records x
JOIN paper_invoice a ON x.invoice_id = a.invoice_id
WHERE year( a.date ) = '2012'
GROUP BY a.invoice_type, Year( a.date ) , Month( a.date ) LIMIT 0 , 30
but it gives results in different rows:
http://www.part.lt/img/1505f0f13172922150febede85ddbf0925.png
But I need it to look like:
Year | Month | SUM_GRYNAIS | SUM_PAVEDIMU
2012 | January | 7597.14997705445 | 58740.2800849304
and ETC.
Try this:
SELECT Year, Month,
MAX(CASE WHEN invoice_type = 'GRYNAIS' THEN sum END) As Sum_GRYNAIS
MAX(CASE WHEN invoice_type = 'PAVEDIMU' THEN sum END) As SUM_PAVEDIMU
FROM
(
SELECT a.invoice_type, year( a.date ) AS Year,
date_format( a.date, '%M' ) AS `month` , Sum( x.amount * x.price ) AS sum
FROM records x JOIN paper_invoice a ON x.invoice_id = a.invoice_id
WHERE year( a.date ) = '2012' GROUP BY a.invoice_type, Year( a.date ) ,
Month( a.date ) LIMIT 0 , 30
)
GROUP BY Year, Month
Because each month has a different value. Try Group By on just the field year.
You are basically looking for PIVOT. MySql doesn't have a PIVOT function but you can still accomplish this. Here is an example of a PIVOT in MySql:
http://www.artfulsoftware.com/infotree/queries.php#78

Oracle to SQLServer conversion

I have the following query in oracle so dont know how to convert into SQL Server.
WITH start_date AS
(
SELECT TO_DATE ( '01-Jan-2010'
, 'DD-Mon-YYYY'
) AS start_date
FROM dual
)
SELECT m.task_name
, COUNT (CASE WHEN TO_CHAR (d.task_date, 'DD') = '01' THEN 1 END) AS Day_1
, COUNT (CASE WHEN TO_CHAR (d.task_date, 'DD') = '02' THEN 1 END) AS Day_2
, COUNT (CASE WHEN TO_CHAR (d.task_date, 'DD') = '03' THEN 1 END) AS Day_3
...
, COUNT (CASE WHEN TO_CHAR (d.task_date, 'DD') = '31' THEN 1 END) AS Day_31
FROM task_master m
JOIN task_detail d ON m.task_id = d.task_id
JOIN start_date s ON d.task_date >= s.start_date
AND d.task_date < ADD_MONTHS (s.start_date, 1)
GROUP BY m.task_name
;
Have a look at using
DATEPART to check the day of month (use d or dd)
and
CONVERT(DATETIME,'01-Jan-2010')
for the Date
and
DATEADD to add the date use DATEADD (datepart ,number,date )