sql nested "sum (case when) or" select query - sql

I have a select query where I am trying to sum a value based on multiple criteria, grouped by dimension. The output will be the sum of the time greater than 30, 90, or 365 days based on the category, grouped by category. I can't crack the syntax for this, I hope you can help!
The concept looks something like this:
select
CATEGORY,
sum (case when
(CATEGORY = '1' and TIME >30) then sum (TIME - 30) or
(CATEGORY = '2' and TIME >90) then sum (TIME - 90) or
(CATEGORY = '3' and TIME >365) then sum (TIME - 365) else 0 end) as output
from database.table
group by CATEGORY
Thanks in advance!

I suspect the syntax you want is:
select CATEGORY,
sum(case when CATEGORY = '1' and TIME > 30 then TIME - 30
when CATEGORY = '2' and TIME > 90 then TIME - 90
when CATEGORY = '3' and TIME > 365 then TIME - 365
else 0
end) as output
from database.table
group by CATEGORY

Related

Calculate difference of data in respective weeks using week number

My data is stored in Google Big QUery in a database. This is how my table looks like. Here Epid_ID is unique for each row and the count is calculated using this value.
Admin_Level_2_district WeekNumber Epid_ID
Jhapa 18 COV-NEP-PR1-SUN-20-00072
Jhapa 19 COV-NEP-PR1-SUN-20-00073
Morang 18 COV-NEP-PR1-SUN-20-00074
Morang 19 COV-NEP-PR1-SUN-20-00075
I want to find the difference in data in two weeks. This is my expected output.
Admin_Level_2_district count_Week_18 count_Week 19 Difference
Jhapa 50 60 10
Morang 60 50 -10
Following is the query I have tried.
SELECT
Admin_Level_2_district,
Week_number,
count(Epid_ID)
FROM `interim-data.casedata.Interim EpiData`
GROUP BY
Admin_Level_2_district,
Week_number
HAVING Week_number = '18'
or Week_number = '19'
Please help!
I think you want conditional aggregation here:
SELECT
Admin_Level_2_district,
COUNT(CASE WHEN WeekNumber = 18 THEN 1 END) AS count_Week_18,
COUNT(CASE WHEN WeekNumber = 19 THEN 1 END) AS count_Week_19,
COUNT(CASE WHEN WeekNumber = 19 THEN 1 END) -
COUNT(CASE WHEN WeekNumber = 18 THEN 1 END) AS Difference
FROM `interim-data.casedata.Interim EpiData`
GROUP BY
Admin_Level_2_district;
You want to use conditional aggregation. In BigQuery, I would recommend countif():
SELECT Admin_Level_2_district,
COUNTIF(week_number = '18') as count_week_18,
COUNTIF(week_number = '19') as count_week_19,
COUNTIF(week_number = '19') - COUNTIF(week_number = '18') as diff
FROM `interim-data.casedata.Interim EpiData`
WHERE Week_number IN ('18', '19')
GROUP BY Admin_Level_2_district;
Note: I would expect week_number to be a number, in which case you would not use single quotes. However, your code treats that as a string, so I left that in.

How to calculate percentage increase between rows in Oracle SQL?

I have data like:
YEAR_MONTH|AVG_VISITS|WAS_MEMBER
2020-09|10|True
2020-09|5|False
2019-04|2.5|True
2019-04|5|False
I'd like to make it into a table that calculates the percentage of visits membership added:
YEAR_MONTH|VISIT_PERCENT
2020-09|200
2019-04|50
What is the SQL that would let me look between rows for this sort of calculation?
You just need conditional aggregation as follows:
select year_month,
100 * sum(case when WAS_MEMBER = 'True' then avg_visits end) /
sum(case when WAS_MEMBER = 'False' then avg_visits end) as perc_increase
from your_table t
group by year_month

Trying to get data for every 6 months

I am running SQL Server and trying to get data for every 6 months.
Here is my query but it is for year, I want it to be every 6 months:
SELECT
DISTINCT YEAR(datein) AS 'Year',
COUNT(*) AS 'Total'
FROM
users
GROUP BY
YEAR(datein)
I want the column value should appear as: MONTH/YEAR
Use month() or quarter() and some arithmetic. Here is one way:
select YEAR(datein) as Year, FLOOR((MONTH(datein) - 1) / 6) as Year_Part,
COUNT(*) as Total
from users
group by YEAR(datein), FLOOR((MONTH(datein) - 1) / 6);
Or, you can put this into two columns:
select year(datein) as year,
sum(case when month(datein) <= 6 then 1 else 0 end) as total_half_1,
sum(case when month(datein) > 6 then 1 else 0 end) as total_half_2
from users
group by year(datein)
order by year(datein);

How to calculate time

I made a table data like below and I want to filter time with category hour -8 and +8.
I made a query like this but wrong result
select resolved_by, count(*) as total,
count (resolution_time > HOUR (resolution_time -8)) as total_target,
count (resolution_time > HOUR (resolution_time +8)) as total_untarget
from all_ticket_closed
where resolved_by = 'Oktadika.Riptono'
group by resolved_by;
For the result, total_target should be 32 and total_untarget 10. how to query it.
Thanks in advance
Probably you may require CASE expression and SUM function for aggregation
SUM (CASE WHEN resolution_time > HOUR THEN (resolution_time -8) ELSE 0 END) as total_target,
SUM (CASE WHEN resolution_time > HOUR THEN (resolution_time +8) ELSE 0 END) as total_untarget

Editing Count(CASE WHEN to sum an Aggregate Value

I am using CASE WHEN in my select statement to count the number of records where a condition is true:
COUNT(CASE WHEN CAST(EVENT_TIMESTAMP AS DATE)
- CONTRACT_EFFECTIVE_DATE = 1 THEN 1 END) AS "1 day",
That works fine.
Now I am attempting to apply the same condition but to sum the values in a column where it is true, rather than counting the records. Here is what I have tried:
(CASE WHEN CAST(EVENT_TIMESTAMP AS DATE)
- CONTRACT_EFFECTIVE_DATE = 0 THEN SUM(DWELL_MINUTES) END) AS "0 day",
But that gave error "Selected non aggregate must be part of the associated group".
I tried some more variations with no success.
How would I sum the values contained in DWELL_MINUTES when CAST(EVENT_TIMESTAMP AS DATE) - CONTRACT_EFFECTIVE_DATE = 0?
You need to change the aggregation function in your original query from COUNT to SUM:
SUM(CASE WHEN CAST(EVENT_TIMESTAMP AS DATE) -
CONTRACT_EFFECTIVE_DATE = 0 THEN DWELL_MINUTES END) AS "0 day"
Do it the other way round, just like with COUNT. Do the evaluation per record and aggregate the results:
SUM(CASE WHEN CAST(EVENT_TIMESTAMP AS DATE)
- CONTRACT_EFFECTIVE_DATE = 0 THEN DWELL_MINUTES END) AS "0 day",