MIN and MAX in case expression - sql

I want to get MIN or Max date base on condition(s.REQUIRED_DATE >= trunc(SYSDATE-1)).
Below is my query.
It gives me error ORA-00937: not a single-group group function
SELECT
case when s.REQUIRED_DATE >= trunc(SYSDATE-1) then
MIN(required_date)
else
MAX(required_date)
end required_date
FROM anytable s
WHERE s.abc = 'hhj';
How can I achieve this?
Query must return 17-AUG-2020 for 'hhj' and 15-AUG-2020 for 'bbj'
id abc required_date
1 hhj 14-Aug-2020
2 hhj 17-AUG-2020
3 hhj 19-AUG-2020
3 bbj 15-AUG-2020
4 bbj 12-AUG-2020
I can adopt any other approach also if required.
Please suggest

It seems, for a particular abc you want to get:
the required_date nearest to and past the date yesterday if there's a required_date past the date yesterday, or
get the latest required_date if they don't pass the date yesterday.
If so, this query may be what you wanted:
select
case when max(required_date)>=trunc(sysdate-1) then
min(case when required_date>=trunc(sysdate-1) then required_date end)
else max(required_date)
end required_date
from anytable s
where s.abc='hhj';

Use Aggregate function on whole case statement and for this you have to use two case statements.
SELECT
MIN(case when s.ENTRY_DATE >= trunc(SYSDATE-1) then
ENTRY_DATE
end) MIN_required_date,
MAX(case when s.ENTRY_DATE < trunc(SYSDATE-1) then
ENTRY_DATE
end) MAX_required_date
FROM DATE_TEST s

Related

Using SUM SEC_TO_TIME in MariaDB

Reference from How to sum time using mysql
I want to SUM Field LogsFormatted.Late Every month with query :
SELECT
SUM(CASE
WHEN MONTH (LogsFormatted.DateIn) = 1
THEN SEC_TO_TIME( SUM( TIME_TO_SEC(LogsFormatted.Late)))
ELSE 0 END
) AS '1'
FROM
HrAttLogsFormatted AS LogsFormatted
But the result is
1111 - Invalid use of group function
Where is the problem with the query? resulting in an error output.. Thank you in advance
[EDIT-SOLVED] It's Solved with simply apply
Change format SUM at the beginning of the query
SEC_TO_TIME(SUM(
CASE WHEN MONTH(LogsFormatted.DateIn) = 1 THEN
TIME_TO_SEC(LogsFormatted.Late) END)
) AS '1'
You don't need to call the sum() so many times. You can also move the case condition to the WHERE clause:
SELECT SUM(TIME_TO_SEC(lf.Late))
FROM HrAttLogsFormatted lf
WHERE MONTH(lf.DateIn) = 1 ;
If you want conditional aggregation, then do:
SELECT SUM(CASE WHEN MONTH(lf.DateIn) = 1 THEN TIME_TO_SEC(lf.Late) END)
FROM HrAttLogsFormatted lf;

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

Getting derived column from database | SQL query | DB2 SystemDate

My table is PRODUCTINFO:
Column name : product_name | launch_date
Sample Date : product1 2017-01-20
I need a SQL query to decide if the product is newly launched or not.
Business rule :
if (launch_date - currentdate < 0 && currentdate - launch_date < 90)
newly_launched = 'YES'
else
newly_launched = 'NO'
where currentdate is today's date.
SQL query I am witting is like :
SELECT launch_date, X as newly_launched
FROM PRODUCTINFO
WHERE product_name = 'product1'
I am not able to figure out correct replacement of 'X' in my query for desired result.
Problem I am facing is using currentdate and if else block in my query
Please help.
One way to get currentdate in DB2 using following query :
SELECT VARCHAR_FORMAT(CURRENT TIMESTAMP, 'YYYYMMDD')
FROM SYSIBM.SYSDUMMY1
Still not sure how to use this with my if else scenario.
Answer here don't solve my problem as this scenario is if-else based.
use TIMESTAMPDIFF with 16 as first parameter for count number days between 2 timestamps, for more detail look here
try this
select launch_date,
case when TIMESTAMPDIFF( 16, cast(cast(launch_date as timestamp) - current timestamp as char(22))) >0 and
TIMESTAMPDIFF( 16, cast(cast(launch_date as timestamp) - current timestamp as char(22))) <90 then 'YES' else 'NO' end newly
from PRODUCTINFO
WHERE product_name = 'product1'
simply use datediff function in a case syntax, I hope it could help!
SELECT launch_date,
case
when DATEDIFF(day,launch_date,getdate()) BETWEEN 0 AND 90 then 'YES'
else 'NO'
end AS newly_launched
FROM PRODUCTINFO
WHERE product_name = 'product1'
in case you want to do it for all your records:
SELECT launch_date,
case
when DATEDIFF(day,launch_date,getdate()) BETWEEN 0 AND 90 then 'YES'
else 'NO'
end AS newly_launched
FROM PRODUCTINFO

SQLite strftime function issue with timezone

I have following table structure where are saved some dates:
I tried to group results by hours using strftime sqlite function, but i found the problem if datetime value is stored like:
2015-01-21 11:49:16CET
In this case is value not converted. But if i erased "CET" value to have something like this:
2015-01-21 10:44:09
I got the correct result.
Query:
SELECT strftime('%H', dc.date) as hr,
COUNT(*) AS DIALS_CNT,
SUM(CASE WHEN dc.call_result = 'APPT' THEN 1 ELSE 0 END) AS APPT_CNT,
SUM(CASE WHEN dc.call_result = 'CONV_NO_APPT' THEN 1 ELSE 0 END) AS CONVERS_CNT,
SUM(CASE WHEN dc.call_result = 'CANNOT_REACH' THEN 1 ELSE 0 END) AS CANNOT_REACH_CNT
FROM dialed_calls dc
GROUP BY strftime('%H', dc.date);
Should i remove timezone from date column or how can i solve it please?
Many thanks for any advice.

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.)