CASE...THEN SELECT AS to produce multiple columns based on condition - sql

I am trying to split up the video_views column into multiple columns based on the date using a SWITCH CASE statement, but this doesn't seem to be achieving the desired results.
SELECT video_views AS
CASE
WHEN date >= '2020-01-01' AND date <= '2020-12-31' THEN video_views END AS video_views_20
WHEN date >= '2021-01-01' AND date <= '2021-12-31' THEN video_views END AS video_views_21
WHEN date >= '2022-01-01' AND date <= '2022-12-31' THEN video_views END AS video_views_22
FROM `table_name'
I expect 3 columns to be produced based on the chosen date ranges.

Related

Suggested way to do a 'parallel period' SQL statement

Let's say I want to get the profit between two dates. Then I can do something like this:
SELECT SUM(Profit)
FROM Sales
WHERE date BETWEEN '2014-01-01' AND '2014-02-01' AND <other_filters>
I would then like to compare it to a previous period offset by a fixed amount. It could be written something like this to get it in two rows:
SELECT SUM(Profit)
FROM Sales
WHERE date BETWEEN '2014-01-01' AND '2014-02-01' AND <other_filters>
UNION ALL
SELECT SUM(Profit)
FROM Sales
WHERE date BETWEEN '2014-01-01' - INTERVAL 1 YEAR AND '2014-02-01' - INTERVAL 1 YEAR AND <other_filters>
Is there a way to do this without a union? I am looking for something like this:
SELECT
SELECT SUM(Profit),
???
FROM Sales
WHERE date BETWEEN '2014-01-01' AND '2014-02-01' AND <other_filters>
I think the tricky part here is how to 'un-do' the where filter for the offseted-time calculation.
You can use conditional aggregation and OR the range checks in the WHERE clause (unless they are subsequent in which case you can combine them directly of course).
SELECT sum(CASE
WHEN date >= '2014-01-01'
AND date < '2014-02-02' THEN
profit
ELSE
0
END),
sum(CASE
WHEN date >= '2014-01-01' - INTERVAL 1 YEAR
AND date < '2014-02-02' - INTERVAL 1 YEAR THEN
profit
ELSE
0
END)
FROM sales
WHERE date >= '2014-01-01'
AND date < '2014-02-02'
OR date >= '2014-01-01' - INTERVAL 1 YEAR
AND date < '2014-02-02' - INTERVAL 1 YEAR;
Note: Prefer not to use BETWEEN here but check for a right half open range check. That way, if the precision of date changes, records on the end past midnight are still in the results.

Group by date intervall Oracle

I want to retrieve sum of weight data from a table over a whole month.
what I need help with is that I want to group the result into 2 parts
sum of 1-15 of the month
and second line 16-31 of the month.
SELECT(SUM(B.SCALE_WEIGHT) FROM TRACKING.DATALOG_TAB B WHERE B.MATERIALID= 1 AND B.SCALE_EVENTDATE BETWEEN TO_DATE(TRUNC(TO_DATE('2020-10-1', 'YYYY-MM-DD'),'MONTH')) AND TO_DATE(TRUNC(TO_DATE('2020-10-1', 'YYYY-MM-DD'), 'MONTH')+30)
GROUP BY(somthing like this - 1-15 and 16-31)
Here is one option:
select
1 + floor(extract(day from scale_eventdate) / 16) as fortnight,
sum(b.scale_weight) as sum_scale_weight
from tracking.datalog_tab b
where
materialid = 1
and scale_eventdate >= date '2020-10-01'
and scale_eventdate < date '2020-11-01'
group by 1 + floor(extract(day from scale_eventdate) / 16)
This extracts the day number from the date, and then use artithmetics: every day from the 1 to to the 15th of the month included goes to fortnight number 1, and everything afterwards goes to bucket 2.
We could also do this with to_char() and a case expression, which is somewhat more expressive:
select
case when to_char(scale_eventdate, 'dd') <= '15' then 1 else 2 end as fortnight,
sum(b.scale_weight) as sum_scale_weight
from tracking.datalog_tab b
where
materialid = 1
and scale_eventdate >= date '2020-10-01'
and scale_eventdate < date '2020-11-01'
group by case when to_char(scale_eventdate, 'dd') <= '15' then 1 else 2 end
Note that I changed the date filtering logic to use standard date literals, which makes the query shorter and more readable.

How to get count of a column between a certain date range without changing the Where clause in SQL

I have a table that has account number, group category and date.
I have a query that does this
Select count(AccNum)
FROM Table
Where date BETWEEN '2020-02-01' AND '2020-03-31'
AND
group IN ('groupA','groupB')
Now is there any way for me to make it work like this
Select count(AccNum) Where date between 2020-02-01 AND '2020-02-31' AS CountFebuary, count(AccNum) Where date between 2020-03-01 AND '2020-02-31' AS CountMarch,
FROM Table
Where date BETWEEN '2020-02-01' AND '2020-03-31'
AND
group IN ('groupA','groupB')
I want to be able to get the total count of accounts for each month without writing a separate query for it. Is that possible?
You can do conditional aggregation:
select
sum(case when date >= '2020-02-01' and date < '2020-03-01' then 1 else 0 end) cnt_february,
sum(case when date >= '2020-03-01' and date < '2020-04-01' then 1 else 0 end) cnt_march
from mytable
where
date >= '2020-02-01' and date < '2020-04-01'
and group IN ('groupA','groupB')
Since you only want two months of data, then we can shorten the conditional expressions a little:
select
sum(case when date < '2020-03-01' then 1 else 0 end) cnt_february,
sum(case when date >= '2020-03-01' then 1 else 0 end) cnt_march
from mytable
where
date >= '2020-02-01' and date < '2020-04-01'
and group IN ('groupA','groupB')
If you are running MySQL, we can shorten some more:
select
sum(date < '2020-03-01') cnt_february,
sum(date >= '2020-03-01') cnt_march
from mytable
where
date >= '2020-02-01' and date < '2020-04-01'
and group IN ('groupA','groupB')
Side note: group is a reserved word in most databases, hence not a good choice for a column name.

using sql to select two different date ranges in database for redshift

I have codes as below:
select date
from date_table
where date between '2019-05-01' and '2019-07-31'
and date between '2020-05-01' and '2020-07-31'
but when i run the code above it shows no rows to display despite i run successfully when only using
select date
from date_table
where date between '2019-05-01' and '2019-07-31'
Does anyone know why?
Presumably you want to OR these two date ranges:
SELECT date
FROM date_table
WHERE
date BETWEEN '2019-05-01' AND '2019-07-31'
OR
date BETWEEN '2020-05-01' AND '2020-07-31';
ANDing together the two ranges will never return any records, since the two ranges are mutually exclusive, and any date can only fall into one of the ranges.
As a side note, if you want to include 1st May 2019 up to, and including, 31st July 2019 (with similar logic on the other range as well), then you should be using inequalities:
SELECT date
FROM date_table
WHERE
date >= '2019-05-01' AND date < '2019-08-01'
OR
date >= '2020-05-01' AND date < '2020-08-01';

How to display result in two column form one column resource with different where

I try to count record which is on current date and pass date from date column
DATE
'2013-03-04 00:00:00'
'2013-02-04 00:00:00'
'2013-02-04 00:00:00'
if today is '2013-03-04 00:00:00'
the result should be
CURRENT_DATE = 1
PASS_DATE = 2
I Don't know how to query it form one resource but different where condition
1st - date >= '2013-03-04 00:00:00'
2nd - date < '2013-03-04 00:00:00'
PLEASE HELP
I suggest using two sub-queries within a SELECT clause
select
(select count(*) from MyDates where DateValue < getdate()) as PastDate,
(select count(*) from MyDates where DateValue >= getdate()) as CurrentDate
You can replace getDate() with a date parameter or a hard-coded value such as '2013-03-04' if you wish.
One way to do it is to query for all dates and place 1\0 according to your condition
then just query again from the table an sum the columns.
SELECT sum([CURRENT_DATE]), sum([PASS_DATE])
FROM
(
SELECT
ID,
case when myDate >= getDate() then 1 else 0 end as [CURRENT_DATE],
case when myDate < getDate() then 1 else 0 end as [PASS_DATE]
FROM mytable
) as SourcTbl
Here is a SQL Fiddle http://sqlfiddle.com/#!3/e9c19/8