How to present a particular SQL queried row as columns in output - sql

I need to present the attached output in PIC1 as the result in PIC2. The query used for generating PIC1 output in SQLDeveloper:
select subs_nm, as_of_date, run_status, (select max (tp.pr_vl)
from ual_mng.tqueue tq, ual_mng.tparams tp, ual_mng.tstatus ts
WHERE tq.tid = tp.tid AND tq.tid = ts.tid and tq.run_id = pcm.run_id and tp.pr_nm in ('TOT_RECORD_CNT')) as RECORD_COUNT
from UAL_MNG.PCM_SUBS_RUN_DTL_VW pcm where SUBS_NM='S_TS2_AQUA_A1_RLAP_DL' and AS_OF_DATE in ('2021-09-01','2021-09-02') order by run_start_dtm desc;
Appreciate all help.

If you don't need it to be dynamic (ie. it will only be two columns and you know which two months they are) you can do
select subs_nm,
max(case when as_of_date = '2021-09-01' then RECORD_COUNT else 0 end) as SEP1,
max(case when as_of_date = '2021-09-02' then RECORD_COUNT else 0 end) as SEP2,
from (
-- Your query
)
group by subs_nm
You can work out the percentage difference using the same expressions.
nb. I would always use an explicit date format mask. This might not run on a different machine / software. So use to_date('2021-09-01', 'yyyy-mm-dd')

Posting the query, which worked in the script :
select subs_nm, SEP1, SEP2, round((((SEP1-SEP2)/SEP1)*100),2) as DIFF_PER from ( select subs_nm,
max(case when as_of_date='2021-09-01' then RECORD_COUNT else '0' end) as SEP1,
max(case when as_of_date='2021-09-02' then RECORD_COUNT else '0' end) as SEP2 from (-- *Main Query*);

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

Find difference between two rows in sql

I have table that stores the employe info in multiple rows and it having the common name for it along with its user login time and log out time for website, and would like to achieve the result and it may contains multiple names such as (N1,N2,N3..etc)
Name,Key,Time,
N1,TotalExp,No
N1,TotalYears,5
N1,LoggedIn,10:00:00
N1,LoggedOut,20:00:00
Expected Output will like below,
N1,TotalExp,TotalYrs,LoggedDifference
N1,No,5,10
Any one help me to achieve this
Even it's a fact that the design of your database doesn't look well, you can query your data this way:
with your_data as (
select 'N1' as Name,'TotalExp' as [Key],'No' as Time union all
select 'N1','TotalYears','5' union all
select 'N1','LoggedIn','10:00:00' union all
select 'N1','LoggedOut','20:00:00'
)
select
Name,
max(case when [Key] = 'TotalExp' then Time else null end) as TotalExp,
max(case when [Key] = 'TotalYears' then Time else null end) as TotalYrs,
datediff(
hour,
max(case when [Key] = 'LoggedIn' then convert(time, Time) else null end),
max(case when [Key] = 'LoggedOut' then convert(time, Time) else null end)
) as LoggedDifference
from your_data
group by Name
You can test on here

SQL Lag and LEAD query

I need data which is in Output column. When 1st column status is P then we need value from Filled date. But once status is anything from P then we need date from last P status. Pls. let me know if i am not able to explain. Thanks in advance.
In standard SQL, you can use:
select (case when status = 'P'
then filled_dt
else lag(case when status = 'P' then filled_dt end) over (partition by mbr_id order by filled_dt ignore nulls)
end) as imputed_filled_dt
This is standard SQL; however, not all databases support ignore nulls. This probably does what you want:
select (case when status = 'P'
then filled_dt
else max(case when status = 'P' then filled_dt end) over (partition by mbr_id order by filled_dt)
end) as imputed_filled_dt

Is there a way to find percentage difference between 2 different days for a specific group?

I need to calculate the percentage difference between 2 days for a specific group in my table.
I need percentage change of column [Group] with the field 'FUND' between days 20190731 and 20190628 by using the column Value. In my example should be -75%.
I hope this works for you:
select prd, grp, 100.0 * (sum(end_value) - sum(start_value)) / sum(start_value)
from
(
select prd, grp,
(case when date = "20190731" then val else 0 end) as end_value,
(case when date = "20190628" then val else 0 end) as start_value
from table1
) as t
group by prd, grp

compare two different date ranges sales in two columns

I want to compare two different date ranges sales in two columns.. I am using query below but its giving wrong sales.. please correct my query
select s1.Itm_cd,s1.Itm_Name,Sum(S1.amount),Sum(s2.amount)
from salestrans s1,salestrans s2
where s1.Itm_cd = S2.Itm_cd
and S1.Tran_dt between '20181101' and'20181130'
and S2.Tran_dt between '20171101' and '20171130'
group by s1.Itm_cd,s1.Itm_Name
Order by s1.Itm_cd
I suspect that you want conditional aggregation here:
WITH cte AS (
SELECT
s1.Itm_cd,
s1.Itm_Name,
SUM(CASE WHEN s1.Tran_dt BETWEEN '20181101' AND '20181130'
THEN s1.amount ELSE 0 END) AS sum_2018,
SUM(CASE WHEN s1.Tran_dt BETWEEN '20171101' AND '20171130'
THEN s1.amount ELSE 0 END) AS sum_2017
FROM salestrans s1
GROUP BY
s1.Itm_cd,
s1.Itm_Name
)
SELECT
Itm_cd,
Itm_Name,
sum_2018,
sum_2017,
CASE WHEN COALESCE(sum_2017, 0) <> 0
THEN FORMAT(100.0 * (sum_2018 - sum_2017) / sum_2017, 'N', 'en-us')
ELSE 'NA' END AS growth_pct
FROM cte
ORDER BY
Itm_cd;
Please try the following
select s1.Itm_cd,s1.Itm_Name,Sum(S1.amount),Sum(s2.amount)
from salestrans s1,salestrans s2
where s1.Itm_cd = S2.Itm_cd
and Convert(Varchar(10),S1.Tran_dt,112) between '20181101' and'20181130'
and Convert(Varchar(10),S2.Tran_dt,112) between '20171101' and '20171130'
group by s1.Itm_cd,s1.Itm_Name
Order by s1.Itm_cd
Here the logic is that in right side while comparision you are providing only date and not any separator and time. The same way should be applied to the column in left side for comparision.
if(Convert(Varchar(10), getdate(),112) = '20181224')
print 'Matched'
else
print 'Not Matched'
if(getdate() = '20181224')
print 'Matched'
else
print 'Not Matched'
Here the output is Matched for first and Not Matched because in first case both side same format has been taken for comparison.