translate aggregate SQL query with case and When to MS Access - sql

I have executed with no problem the query in SQL but it does not work in Access
Case is not avaliable in Access right, so IIf must be used...
select
sum(case when date between '2012-05-01' AND '2012-06-01' then value else 0 end) as sum1,
sum(case when date between '2012-05-01' AND '2012-10-01' then value else 0 end) as sum2,
sum(case when situation like 'Urgent' then 1 else 0 end) as urgent,
sum(case when situation like 'Anual' then 1 else 0 end) as anual,
sum(1) as total
from mytable
Is there a better way of doing this?
Will this query work?
select
sum(IIf date between '2012-05-01' AND '2012-06-01',value,0) as sum1,
sum(IIf date between '2012-05-01' AND '2012-10-01',value,0) as sum2,
sum(IIf situation like 'Urgent',1,0 ) as urgent,
sum(IIf situation like 'Anual' ,1,0 ) as anual,
sum(1) as total
from mytable

You need parentheses for IIf() as in IIf(expression, truepart, falsepart)
Enclose date and value in square brackets because both are reserved words.
Your Like comparisons didn't include any pattern matching, so I substituted = instead.
I assumed date is Date/Time data type, so enclosed the values with the # delimiter.
SELECT
Sum(IIf([date] BETWEEN #2012-05-01# AND #2012-06-01#,[value],0)) AS Sum1,
Sum(IIf([date] BETWEEN #2012-05-01# AND #2012-10-01#,[value],0)) AS Sum2,
Sum(IIf(situation = 'Urgent',1,0 )) AS urgent,
Sum(IIf(situation = 'Anual' ,1,0 )) AS anual,
Sum(1) AS total
FROM mytable;

Related

How select second max value from a subquery

I need to select a max date (DATA_RIF_PATR_KU) for the key PROT, CODICE_COM, but there are also 9999-12-31 values. So when there are others date than 9999-12-31 I need to select the "real max date" else 9999-12-31.
For example:
For the combination:
PROT = '202000060300' AND
CODICE_COM='Z01'
I have 2 dates of DATA_RIF_PATR_KU: 03-11-20, 9999-12-31. I need to select the first one.
I wrote this code:
'''
SELECT
A.GRADO,
A.COMM,
A.PROT,
MAX(A.FLAG_VAL_IND) AS FLAG_VAL_IND,
SUM(A.CONT_VERS) AS CONT_VERS,
SUM(A.IMP_PREN) AS IMP_PREN,
SUM(A.CONT_DIFF) AS CONT_DIFF,
MIN(A.DATA_VER) AS DATA_VER,
MAX(A.PREN_DEB) AS PREN_DEB,
MAX(A.PREN_DEB_VER) AS PREN_DEB_VER,
MAX(A.GRAT_PATR_KU) AS GRAT_PATR_KU,
MAX(CASE WHEN (A.MAX_DATA_RIF_PATR_NON_9999)='SI' THEN A.DATA_RIF_PATR_KU
WHEN (A.MAX_DATA_RIF_PATR_NON_9999_2)='SI2' THEN A.DATA_RIF_PATR_KU END) AS DATA_RIF_PATR_KU,
SUM(A.MAGG_PEC) AS MAGG_PEC,
MAX(A.ASS_PEC) AS ASS_PEC,
MAX(A.ASS_CF) AS ASS_CF,
MAX(A.ASS_VAL) AS ASS_VAL,
MAX(A.FLAG_LAV) AS FLAG_LAV,
SUM(A.CONT_DIC) AS CONT_DIC,
SUM(A.CONT_TOT) AS CONT_TOT,
SUM(A.CONT_DIFF_VERIF) AS CONT_DIFF_VERIF,
MAX(A.DATA_AGG) AS DATA_ULTIMA_VALIDAZIONE,
MAX(CASE WHEN (A.DATA_INV)<'9999-12-31'
THEN '1'
ELSE '0' END) AS PRESENZA_INVITO_PAG,
MAX(CASE WHEN (A.DATA_VERS_INV)<'9999-12-31'
THEN '1'
ELSE '0' END) AS PRESENZA_VERS_INVITO
FROM
(
SELECT
distinct BILS05_GRADO AS GRADO,
BILS05_CODICE_COM AS COMM,
BILS05_PROT AS PROT,
CASE WHEN BILS05_FLAG_VAL_IND IN ('0','9')
THEN 'D'
ELSE 'I' END AS FLAG_VAL_IND,
bils05_tipo_doc, bils05_prog_alleg, bils05_pren_deb as pren_deb,
BILS05_PREN_DEB_VERIF AS PREN_DEB_VER,
CASE WHEN BILS05_PREN_DEB='1' AND BILS05_PREN_DEB_VERIF='1'
THEN 0
ELSE BILS05_CONT_VERS_VERIF END AS CONT_VERS,
CASE WHEN BILS05_PREN_DEB='1' AND BILS05_PREN_DEB_VERIF='1'
THEN BILS05_CONT_VERS_VERIF
ELSE 0 END AS IMP_PREN,
BILS05_CONT_DIFF AS CONT_DIFF,
BILS05_DATA_ACQ_KU AS DATA_VER,
BILS05_MAGG_PEC AS MAGG_PEC,
BILS05_ASS_PEC AS ASS_PEC,BILS05_ASS_CF AS ASS_CF,BILS05_ASS_VAL AS ASS_VAL,
BILS05_FLAG_LAV AS FLAG_LAV,
BILS05_CONT_VERS AS CONT_DIC,
BILS05_CONT_TOT AS CONT_TOT,
BILS05_CONT_DIFF_VERIF AS CONT_DIFF_VERIF,
BILS05_DATA_AGG_KU AS DATA_AGG,
BILS05_DATA_INV_PAG AS DATA_INV,
BILS05_DATA_VERS_INV AS DATA_VERS_INV,
BILS05_GRAT_PATR as GRAT_PATR_KU,
BILS05_DATA_RIF_PATR AS DATA_RIF_PATR_KU,
ROW_NUMBER() OVER(PARTITION BY BILS05_PROT, BILS05_CODICE_COM ORDER BY BILS05_DATA_RIF_PATR) AS RN,
LEAD(DATA_RIF_PATR_KU) OVER(PARTITION BY BILS05_PROT, BILS05_CODICE_COM ORDER BY DATA_RIF_PATR_KU) AS FOLLOW_DATA,
LAG(DATA_RIF_PATR_KU) OVER(PARTITION BY BILS05_PROT, BILS05_CODICE_COM ORDER BY DATA_RIF_PATR_KU) AS PREV_DATA,
CASE WHEN (DATA_RIF_PATR_KU < FOLLOW_DATA AND DATA_RIF_PATR_KU NOT = '9999-12-31' AND FOLLOW_DATA='9999-12-31' )THEN 'SI'
ELSE 'NO' END AS MAX_DATA_RIF_PATR_NON_9999,
CASE WHEN (DATA_RIF_PATR_KU NOT = '9999-12-31' AND FOLLOW_DATA IS NULL) OR (DATA_RIF_PATR_KU = '9999-12-31' AND FOLLOW_DATA IS NULL)
THEN 'SI2' ELSE 'NO' END AS MAX_DATA_RIF_PATR_NON_9999_2
FROM ZUCOW.BILS05
WHERE
BILS05_FLAG_LAV='2'
) A
WHERE
A.PROT='202000060300' AND
A.COMM='Z01'
GROUP BY A.GRADO, A.COMM, A.PROT;
'''
but it doesn't work properly. It select 9999-12-31 instead of 03-11-20 in the above example
Your example is rather long and complex, but the general idea would be
(assuming DATA_RIF_PATR_KU is a date field):
select
max(case when DATA_RIF_PATR_KU='9999-12-31' then null else DATA_RIF_PATR_KU end),
PROT, CODICE_COM
FROM FROM ZUCOW.BILS05
GROUP BY 2,3
yes that's the general idea.. Anyway at the end, I solved it in another way:
MAX(CASE WHEN TO_CHAR(A.DATA_RIF_PATR_KU, 'YYYY-MM-DD' ) LIKE ('9999-12-31')THEN '0000-12-31' ELSE TO_CHAR(A.DATA_RIF_PATR_KU, 'YYYY-MM-DD') END) AS DATA_RIF_PATR_KU_STR
So, I converted the 9999-12-31 values in 0000-12-31 (I had to to transform the date value in string), so then I could do the max and then I converted the values back in the ETL software.
Thank You all for helping

SQL CASE WHEN THEN logics of calculating the types of a column

Have a tableA like this:
I wanna receive a tableŠ˜ like this (group by startTime and endTime, count of Severity in cnt column and count of every type of Severity in a distinct column):
The simple count (cnt column) works fine. But with the other I tired CASE WHEN THEN logics and it seems not working (line 10 for example). Can you please assist me with SQL query in this case.
You need conditional aggregation :
select starttime, endtime, count(*),
sum(case when severity = 'low' then 1 else 0 end),
sum(case when severity = 'med' then 1 else 0 end),
sum(case when severity = 'high' then 1 else 0 end)
from table t
group by starttime, endtime;
Try below query: with case when
select starttime, endtime, count(severity) as cnt, count(case when severity='LOW' then 1 end) cnt_low,count(case when severity='MED' then 1 end) cnt_med,count(case when severity='HIGH' then 1 end) as cnt_high
from tablename
group by starttime, endtime
use case when and aggregate function sum
select startTime , endTime,count(*) as Cnt,
sum( case when Severity='MED' then 1 else 0 end) as cntMed,
sum( case when Severity='LOW' then 1 else 0 end) as cntLow,
sum( case when Severity='HIGH' then 1 else 0 end) as cntHIGH from yourtable
group by startTime , endTime

SQL - how to SUM two Count Statements to create a Total Column

i have the following query and for the life of me have forgotton how to SUM both columns to create a 'Total' column
SELECT username as 'username',
count (case when casestype <> 'car'
OR casestype <> 'van'
OR casestype <> 'bike'
OR casestype <> 'NONE'
THEN 1 ELSE NULL END) as 'non-auto',
count (case when casestype = 'car'
OR casestype= 'van'
OR casestype = 'bike'
THEN 1 ELSE NULL END) as 'auto'
FROM Case WITH (NOLOCK)
WHERE CaseDate BETWEEN '01 may 2016' AND '31 may 2016')
GROUP BY username
I want to have a total column of non-auto + auto
SELECT username,
sum(case when casestype not in ('car', 'van', 'bike', 'NONE')
then 1 else 0
end) as non_auto,
sum(case when casestype in ('car', 'ban', 'bike') then 1 else 0
end) as auto,
sum(case when casestype <> 'NONE' then 1 else 0 end) as total
FROM [Case]
WHERE CaseDate BETWEEN '2016-05-01' and '2016-05-31'
GROUP BY username;
Additional advice:
in and not in are much more readable than a series of or statements.
Use ISO standard date formats. YYYY-MM-DD is my preference, although SQL Server has a slight preference for YYYYMMDD.
The total needs to be calculated separately. If you want to use column aliases you need subqueries or CTEs.
Don't use single quotes for column aliases. Only use them for string and date constants.

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

Do several aggregates in one query using where clause SQL

Is it possible to do several aggregate functions inside a single query
I know whe can use
SELECT SUM(value) FROM mytable WHERE date between '2012-05-01' AND '2012-06-01'
I've been trying to make an example
CREATE TABLE mytable
(id varchar(10), value int, `date` date, situation varchar(10) ) ;
INSERT INTO mytable
(id, value, date, situation)
VALUES
('id0', 1338, '2012-05-14','Urgent'),
('id0', 3572, '2012-05-13','Urgent'),
('id0', 3232, '2012-05-06','Urgent'),
('id0', 3068, '2012-05-05','Post'),
('id0', 3363, '2012-05-04','Urgent'),
('id0', 2022, '2012-04-28','Anual'),
('id0', 3193, '2012-04-24','Post')
But is it possible to use the same query to get other aggregate values?
SELECT SUM(value),SUM(value),Count(*) FROM mytable WHERE date between '2012-05-01' AND '2012-06-01', WHERE date between '2012-05-01' AND '2012-10-01', Where situation like 'Urgent'
instead of 3 queries:
SELECT SUM(value) FROM mytable WHERE date between '2012-05-01' AND '2012-06-01'
SELECT SUM(value) FROM mytable WHERE date between '2012-05-01' AND '2012-10-01'
SELECT Count(*) FROM mytable Where situation like 'Urgent'
use case
select
sum(case when date between '2012-05-01' AND '2012-06-01' then value else 0 end) as sum1,
sum(case when date between '2012-05-01' AND '2012-10-01' then value else 0 end) as sum2,
sum(case when situation like 'Urgent' then 1 else 0 end) as count1
from mytable
You can
SELECT
SUM(CASE WHEN date between '2012-05-01' AND '2012-06-01' THEN value ELSE 0 END)
as sum1,
SUM(CASE WHEN date between '2012-05-01' AND '2012-10-01' THEN value ELSE 0 END)
as sum2,
COUNT(CASE WHEN situation like 'Urgent%' THEN 1 ELSE 0 END)
as cnt1
FROM mytable Where situation like 'Urgent%' OR date between '2012-05-01' AND '2012-10-01'
I guess you missed % in like : like 'Urgent%', not like 'Urgent'.