Editing Count(CASE WHEN to sum an Aggregate Value - sql

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",

Related

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

Converting dates into weekdays then correlating it and summing it

The query is simple but not functioning the way I want it,
I am trying to check the date I inspected is the correct day I am checking against.
Input
SELECT TO_CHAR(date '1982.03.09', 'DAY'),
(CASE When lower(TO_CHAR(date '1982.03.09', 'DAY')) like lower('TUESDAY')
then 1 else 0 end)
Output
The answer should have been 1 for the case statement.
I added lower to check if it had to something with the capitals
Reason
The reason why I use a case statement is because when a student has an afterschool activity on monday, I want to place either 1 or 0 in the table and calculate the sum of how many students have afterschool acitivity on monday and so on.
Need eventually
I am doing this so that I can create a table of the week with the number of children doing aftershool activities for each day.
Any help regarding fixing my query would be greatly appreciated!
Thanks
For whatever reason there are spaces behind the TUESDAY to_char() produces. You can trim() them away. But instead of relying on a string representation (that probably might change when the locale changes) you should better use extract() to get the day of the week in numerical representation, 0 for Sunday, 1 for Monday and so on.
SELECT to_char(DATE '1982.03.09', 'DAY'),
CASE
WHEN trim(to_char(DATE '1982.03.09', 'DAY')) = 'TUESDAY' THEN
1
ELSE
0
END,
CASE extract(dow FROM DATE '1982.03.09')
WHEN 2 THEN
1
ELSE
0
END;
I'm a personal fan of extract (<datepart> from <date>) in lieu of to_char for problems like this.
Based on the output you are trying to achieve, I might also recommend a poor man's pivot table:
select
student_id,
max (case when extract (dow from activity_date) = 1 then 1 else 0 end) as mo,
max (case when extract (dow from activity_date) = 2 then 1 else 0 end) as tu,
max (case when extract (dow from activity_date) = 3 then 1 else 0 end) as we,
max (case when extract (dow from activity_date) = 4 then 1 else 0 end) as th,
max (case when extract (dow from activity_date) = 5 then 1 else 0 end) as fr
from activities
where activity_date between :FROM_DATE and :THRU_DATE
group by
student_id
Normally this would be a good use case for filter (where, but that would leave null values on date/student records where there is no activity. Depending on how you render your output, that may or may not be okay (Excel would handle it fine).
select
student_id,
max (1) filter (where extract (dow from activity_date) = 1) as mo,
max (1) filter (where extract (dow from activity_date) = 2) as tu,
max (1) filter (where extract (dow from activity_date) = 3) as we,
max (1) filter (where extract (dow from activity_date) = 4) as th,
max (1) filter (where extract (dow from activity_date) = 5) as fr
from activities
group by
student_id

Counting null and missing values using RODBC package

I am working to create a a matrix of missingness for a SQL database consisting of 5 tables and nearly 10 years of data. I have established ODBC connectivity and am using the RODBC package in R as my working environment. I am trying to write a function that will output a count of rows for each year for each table, a count and percent of null values (values not present) in a given year for a given table, and a count and percent of missing (questions skipped/not answered) values for a given table. I have written the code below, trying to get it to work on one variable then turning it into a function once it works. However, when I run this code, the count for total, missing and null values are all the same and the percent of course is 1. I am not getting any error messages. I am not sure where the issue lies and it is important to distinguish between missing and null for this project. Any insight is much appreciated.
test1 <- sqlQuery(channel, "
SELECT [event_year] AS 'YEAR',
Count(*) AS 'TOTAL',
Count(CASE
WHEN mother_education_trendable = 'NA' THEN 1
ELSE 0
END) AS 'NULL_VAL',
Count(CASE
WHEN mother_education_trendable = -1 THEN 1
ELSE 0
END) AS 'MISS_VAL'
FROM [GA_CMH].[dbo].[births]
GROUP BY [event_year]
ORDER BY [event_year]
")
test1$nullpct<-with(test1, NULL_VAL/TOTAL)
test1$misspct<-with(test1, MISS_VAL/TOTAL)
Your current CASE statement inside the Count aggregate will populate either 1 or 0 both will be considered in Count aggregate so you are getting same count as total.
Zero is a value that will be counted in Count aggregate so remove the ELSE part in CASE statement by default NULL will be populated non matching conditions which will not be counted/considered in COUNT aggregate
SELECT [event_year] AS 'YEAR',
Count(*) AS 'TOTAL',
Count(CASE
WHEN mother_education_trendable = 'NA' THEN 1
END) AS 'NULL_VAL',
Count(CASE
WHEN mother_education_trendable = -1 THEN 1
END) AS 'MISS_VAL'
FROM [GA_CMH].[dbo].[births]
GROUP BY [event_year]
ORDER BY [event_year]
Or use SUM aggregate instead of COUNT
SELECT [event_year] AS 'YEAR',
Count(*) AS 'TOTAL',
SUM(CASE
WHEN mother_education_trendable = 'NA' THEN 1 ELSE 0
END) AS 'NULL_VAL',
SUM(CASE
WHEN mother_education_trendable = -1 THEN 1 ELSE 0
END) AS 'MISS_VAL'
FROM [GA_CMH].[dbo].[births]
GROUP BY [event_year]
ORDER BY [event_year]

How to use a case or decode as part of an analytical window function in Oracle SQL

I would like to do something like this:
select sum(nvl(total_time_out, 0)),
sum(nvl((case when day_of_week = 'Mon' then total_time_out else 0 end) over (partition by person_id), 0))
from xxpay_tna_summary_v
where person_id = 7926
where the second column only returns the sum of the total time out hours for the Monday. Is this possible in Oracle SQL, and what is the correct syntax?
check this
http://sqlfiddle.com/#!4/df376/2
select sum((case when person_id = 100 then total_time_out else 0 end)) total_time,
sum(nvl((case when day_of_week = 'MON' then total_time_out else 0 end), 0)) monday_time
from xxpay_tna_summary_v
Your syntax is invalid, because sum belongs to over, but you moved the sum keyword to the beginning of the expression. Here is the corrected statement:
select nvl(sum(total_time_out), 0),
nvl(sum(case when day_of_week = 'Mon' then total_time_out else 0 end) over (partition by person_id), 0)
from xxpay_tna_summary_v
where person_id = 7926;
(I also changed places for sum and nvl in your first expression. It does the same but might be nanoseconds faster, because nvl has to be applied just once.)