Cognos Report Studio 10.2.2 case statement sql logic - sql

I am trying to get this sql logic to work and the last part is where i do not have my logic correct.
I need to bring back readmits for providers that have listed as ID_1 & ID_2. If a person has a readmit within 30 days then they get a readmit_conf_30 number even if they went to another place. I need to have the original provider numbers and the other providers in the report if they have a readmit within 30 days of of each other.
I have tried many ways and am at a loss for how to word it. Group1 is for providers that i am looking for. Group2 is for other providers. Group3 unions them together and Group4 i try to assign them Y/N whether i want them on report. That is where i need help in the case logic.
Thanks for the help.
Code:
WITH Group1 AS
(
SELECT
A.MEMBER, B.SEX, B.DOB, B.LAST_NAME, B.FIRST_NAME,
A.PROVIDER_ID, C.PROVIDER_NAME, A.CONF_NUM, A.BEG_DT, A.END_DT, A.TOS_I_4, A.DIS_STAT, A.AMT_EQV, A.AMT_PAY, A.AMT_REQ
, A.READMIT_INDEX_30, A.READMIT_30, A.READMIT_CONF_30, '04/30/2014' as DateCheck
, '341425870018' AS ID_1
, '341425870052' AS ID_2
FROM CONFINEMENTS A
LEFT JOIN MEMINFO B ON A.MEMBER = B.MEMBER
LEFT JOIN PROVINFO C ON A.PROVIDER_ID = C.PROVIDER_ID
LEFT JOIN MAP_DATE_RANGE D ON D.IA_TIME = A.IA_TIME
WHERE
A.CUST_OPL_MED IN ('A$*', 'B$*', 'N$*', 'P$*', 'D$*', ' 'Unspecified$UNK')
AND A.BEG_DT >= '05/01/2013' and A.beg_dt <'05/01/2014'
and A.PROVIDER_ID Like '341425870%'
and (A.READMIT_30 = 1 OR A.READMIT_30 = 0)
--AND A.DIS_STAT <> 20
),
GROUP2 AS (
SELECT
A.MEMBER, B.SEX, B.DOB, B.LAST_NAME, B.FIRST_NAME, A.PROVIDER_ID, C.PROVIDER_NAME
, A.CONF_NUM, A.BEG_DT, A.END_DT, A.TOS_I_4, A.DIS_STAT, A.AMT_EQV, A.AMT_PAY, A.AMT_REQ
, A.READMIT_INDEX_30, A.READMIT_30, A.READMIT_CONF_30, '04/30/2014' as DateCheck
, '341425870018' AS ID_1
, '341425870052' AS ID_2
FROM CONFINEMENTS A
LEFT JOIN MEMINFO B ON A.MEMBER = B.MEMBER
LEFT JOIN PROVINFO C ON A.PROVIDER_ID = C.PROVIDER_ID
LEFT JOIN MAP_DATE_RANGE D ON D.IA_TIME = A.IA_TIME
WHERE
A.CUST_OPL_MED IN ('A$*', 'B$*', 'N$*', 'P$*', 'D$*', 'Unspecified$UNK')
AND A.BEG_DT >= '05/01/2013' and A.beg_dt <'05/01/2014'
--and A.PROVIDER_ID Like '341425870%'
and (A.READMIT_30 = 1 OR A.READMIT_30 = 0)
--AND A.DIS_STAT <> 20
),
GROUP3 AS (
Select *, DATEADD(dd, 30, datecheck) AS MaxdateAllowed from Group1
union
select *, DATEADD(dd, 30, datecheck) AS MaxdateAllowed from GROUP2
),
Group4 AS (
select *
, case when PROVIDER_ID <> ID_1 and readmit_conf_30 is not null THEN 'Y'
when PROVIDER_ID <> ID_2 and readmit_conf_30 is not null THEN 'Y'
when PROVIDER_ID = ID_1 and readmit_conf_30 is not null THEN 'Y'
when PROVIDER_ID = ID_2 and readmit_conf_30 is not null THEN 'Y'
when PROVIDER_ID = ID_1 THEN 'Y'
when PROVIDER_ID = ID_2 THEN 'Y'
when PROVIDER_ID <> ID_1 THEN 'N'
when PROVIDER_ID <> ID_2 THEN 'N'
ELSE 'B'
END AS GoodRecord
FROM Group3
where maxdateallowed > beg_dt and READMIT_INDEX_30 = 1
--and (READMIT_30 = 1 OR READMIT_30 = 0)
)
SELECT * FROM Group4
WHERE GoodRecord = 'Y'
order by conf_num

I figured it out.
SQL Code Below :-
WITH Group1 AS (
SELECT A.MEMBER, B.SEX, B.DOB, B.LAST_NAME, B.FIRST_NAME, A.PROVIDER_ID, C.PROVIDER_NAME
, A.CONF_NUM, A.BEG_DT, A.END_DT, A.TOS_I_4, A.DIS_STAT, A.AMT_EQV, A.AMT_PAY, A.AMT_REQ
, A.READMIT_INDEX_30, A.READMIT_30, A.READMIT_CONF_30
FROM CONFINEMENTS A
LEFT JOIN MEMINFO B ON A.MEMBER = B.MEMBER
LEFT JOIN PROVINFO C ON A.PROVIDER_ID = C.PROVIDER_ID
LEFT JOIN MAP_DATE_RANGE D ON D.IA_TIME = A.IA_TIME
WHERE A.CUST_OPL_MED IN ('A$*', 'B$*', 'N$*', 'P$*', 'D$*', 'Unspecified$UNK')
AND A.BEG_DT >= '05/01/2013' and A.beg_dt <'05/01/2014'
and A.PROVIDER_ID Like '341425870%'
and (A.READMIT_30 = 1 OR A.READMIT_30 = 0)
),
GROUP2 AS (
SELECT AA.MEMBER, AA.READMIT_CONF_30
FROM Group1 AA
WHERE AA.READMIT_CONF_30 > 0
),
Group3 AS (
Select AA.MEMBER, A.READMIT_CONF_30, A.CONF_NUM
,B.SEX, B.DOB, B.LAST_NAME, B.FIRST_NAME, A.PROVIDER_ID, C.PROVIDER_NAME
, A.BEG_DT, A.END_DT, A.TOS_I_4, A.DIS_STAT, A.AMT_EQV, A.AMT_PAY, A.AMT_REQ
, A.READMIT_30, A.READMIT_INDEX_30
FROM GROUP2 AA
LEFT JOIN CONFINEMENTS A ON A.MEMBER = AA.MEMBER AND AA.READMIT_CONF_30 = A.CONF_NUM
LEFT JOIN MEMINFO B ON A.MEMBER = B.MEMBER
LEFT JOIN PROVINFO C ON A.PROVIDER_ID = C.PROVIDER_ID
LEFT JOIN MAP_DATE_RANGE D ON D.IA_TIME = A.IA_TIME
WHERE A.CUST_OPL_MED IN ('A$*', 'B$*', 'N$*', 'P$*', 'D$*', 'Unspecified$UNK')
and (A.READMIT_30 = 1 OR A.READMIT_30 = 0)
)
select
MEMBER, READMIT_CONF_30
,SEX, DOB, LAST_NAME, FIRST_NAME, PROVIDER_ID, PROVIDER_NAME
, CONF_NUM, BEG_DT, END_DT, TOS_I_4, DIS_STAT, AMT_EQV, AMT_PAY, AMT_REQ
, READMIT_30, READMIT_INDEX_30
from group1
union
select
MEMBER, READMIT_CONF_30
,SEX, DOB, LAST_NAME, FIRST_NAME, PROVIDER_ID, PROVIDER_NAME
, CONF_NUM, BEG_DT, END_DT, TOS_I_4, DIS_STAT, AMT_EQV, AMT_PAY, AMT_REQ
, READMIT_30, READMIT_INDEX_30
from Group3
order by conf_num

Related

Check col1 if duplicate then check col2 if distinct

Hey guys I've been struggling to get a simple query done in SnowFlake.
A sample of the data is explained below,
Number
ID
2559
23
2559
33
2559
55
2550
89
2499
14
2499
14
Based on the table above I would like to create a column that checks if (column Number) have duplicated values if yes; then check (column ID) if the values associated with that Number were duplicated or distinct. If values were duplicated then return 0 if values were distinct then return 1.
The desired outcome is as follows,
Number
ID
Check
2559
23
1
2559
33
1
2559
55
1
2550
89
0
2499
14
0
2499
14
0
and the last outcome should be on the Number column level (group by) and would be like the following table,
Number
Check
2559
1
2550
0
2499
0
Any suggestions are appreciated.
Edited tables
The scenario has changed based on new requirements
The original table have two IDs (ID1 and ID2) and those IDs must be linked to two different tables T-ID1 and T-ID2.
Number
ID1
ID2
2559
23
null
2559
33
null
2559
55
null
2550
89
null
2499
14
null
2499
14
null
2498
null
14
2498
null
50
2498
null
null
So the idea is if Number has duplicated IDs (in ID1 or ID2) then return 1, if Number has unique ID (in ID1 or ID2) then return ID1 or ID2. if Number have null values for ID1 and ID2 then ignore the entire row.
This is the query I am using - everything works based on solution provided below, but I am getting nulls along with ID values.
ID1 is linked to Supplier_ID_Ekuep and ID2 is linked to Supplier_ID_Qava.
select wbd.WAYBILL_ID, sup.WAYBILL_NO,
sup.Supplier_ID_Qava, supq.Supplier_Qava, supq.Supllier_City_Qava, supq.Supplier_Qava_Add,
sup.Supplier_ID_Ekuep, supc.Supplier_Ekuep, supc.Supllier_City_Ekuep, supc.Supplier_Ekuep_Add
from WAYBILL_PRODUCTS wbd
left join (select wb.WAYBILL_ID, ow.WAYBILL_NO,
case when mult.multi_supp_qava = 1 then '1'
when mult.multi_supp_qava = 0 then op.ID_Supplier_Qava
else null end as Supplier_ID_Qava,
case when mult.multi_supp_ekuep = 1 then '1'
when mult.multi_supp_ekuep = 0 then op.ID_Supplier_Ekuep
else null end as Supplier_ID_Ekuep
from WAYBILL_PRODUCTS wb
left join (select ID, ORDER_ID, WAYBILL_NO from ORDER_WAYBILLS) ow on wb.WAYBILL_ID = ow.id
left join (select opr.ID_ORDER, opr.ID_PRODUCT, ss.ID_Supplier_Ekuep, ss.ID_Supplier_Qava
from ORDER_PRODUCTS opr
left join (select s.id, supc.*, supq.*
from SUPPLIERS s
left join (select ID_SUPPLIER as ID_Supplier_Ekuep
from EKUEP_KSA_EKUEP_STAGING.PS_SUPPLIER where USED_SUPPLIER_ID is null) supc on supc.ID_Supplier_Ekuep = s.ID_SUPPLIER and s.STORE_ID = 1
left join (select ID_SUPPLIER as ID_Supplier_Qava
from QAVASHOP_KSA_QAVAISH_MAINSHOP.PS_SUPPLIER where USED_SUPPLIER_ID is null) supq on supq.ID_Supplier_Qava = s.ID_SUPPLIER and s.STORE_ID = 2) ss on opr.SUPPLIER_ID = ss.ID
group by opr.ID_ORDER, opr.ID_PRODUCT, ss.ID_Supplier_Ekuep, ss.ID_Supplier_Qava) op on op.ID_PRODUCT = wb.PRODUCT_ID and op.ID_ORDER = ow.ORDER_ID
------------------------------------------------------------------------------------------------------------------------
left join (select wb.WAYBILL_ID, ow.WAYBILL_NO,
(count(distinct op.ID_Supplier_Qava) > 1)::int as multi_supp_qava,
(count(distinct op.ID_Supplier_Ekuep) > 1)::int as multi_supp_ekuep
from WAYBILL_PRODUCTS wb
left join (select ID, ORDER_ID, WAYBILL_NO from ORDER_WAYBILLS) ow on wb.WAYBILL_ID = ow.id
left join (select opr.ID_ORDER, opr.ID_PRODUCT, ss.ID_Supplier_Ekuep, ss.ID_Supplier_Qava
from ORDER_PRODUCTS opr
left join (select s.id, supc.ID_Supplier_Ekuep, supq.ID_Supplier_Qava
from SUPPLIERS s
left join (select ID_SUPPLIER as ID_Supplier_Ekuep
from EKUEP_KSA_EKUEP_STAGING.PS_SUPPLIER where USED_SUPPLIER_ID is null) supc on supc.ID_Supplier_Ekuep = s.ID_SUPPLIER and s.STORE_ID = 1
left join (select ID_SUPPLIER as ID_Supplier_Qava
from QAVASHOP_KSA_QAVAISH_MAINSHOP.PS_SUPPLIER where USED_SUPPLIER_ID is null) supq on supq.ID_Supplier_Qava = s.ID_SUPPLIER and s.STORE_ID = 2
) ss on opr.SUPPLIER_ID = ss.ID
group by opr.ID_ORDER, opr.ID_PRODUCT, ss.ID_Supplier_Ekuep, ss.ID_Supplier_Qava) op on op.ID_PRODUCT = wb.PRODUCT_ID and op.ID_ORDER = ow.ORDER_ID
where _FIVETRAN_DELETED = 0
group by wb.WAYBILL_ID, ow.WAYBILL_NO) mult on mult.WAYBILL_NO = ow.WAYBILL_NO
------------------------------------------------------------------------------------------------------------------------
group by wb.WAYBILL_ID, ow.WAYBILL_NO, mult.multi_supp_qava, mult.multi_supp_ekuep, op.ID_Supplier_Qava, op.ID_Supplier_Ekuep) sup on wbd.WAYBILL_ID = sup.WAYBILL_ID
left join
(select ps.ID_SUPPLIER as ID_Supplier_Qava,
ps.name as Supplier_Qava,
listagg(distinct pa.CITY, ', ') as Supllier_City_Qava,
ps.DATE_ADD as Supplier_Qava_Add
from QAVASHOP_KSA_QAVAISH_MAINSHOP.PS_SUPPLIER ps
left join (select * from QAVASHOP_KSA_QAVAISH_MAINSHOP.PS_ADDRESS) pa on pa.ID_SUPPLIER = ps.ID_SUPPLIER and pa._FIVETRAN_DELETED = 0
where ps.USED_SUPPLIER_ID is null and ps._FIVETRAN_DELETED = 0
group by ID_Supplier_Qava, Supplier_Qava, Supplier_Qava_Add) supq on supq.ID_Supplier_Qava = sup.Supplier_ID_Qava
left join
(select ps.ID_SUPPLIER as ID_Supplier_Ekuep,
ps.name as Supplier_Ekuep,
listagg(distinct pa.CITY, ', ') as Supllier_City_Ekuep,
ps.DATE_ADD as Supplier_Ekuep_Add
from EKUEP_KSA_EKUEP_STAGING.PS_SUPPLIER ps
left join (select * from EKUEP_KSA_EKUEP_STAGING.PS_ADDRESS) pa on pa.ID_SUPPLIER = ps.ID_SUPPLIER and pa._FIVETRAN_DELETED = 0
where ps.USED_SUPPLIER_ID is null and ps._FIVETRAN_DELETED = 0
group by ID_Supplier_Ekuep, Supplier_Ekuep, Supplier_Ekuep_Add) supc on supc.ID_Supplier_Ekuep = sup.Supplier_ID_Ekuep
where _FIVETRAN_DELETED = 0
group by wbd.WAYBILL_ID, sup.WAYBILL_NO,
sup.Supplier_ID_Qava, supq.Supplier_Qava, supq.Supllier_City_Qava, supq.Supplier_Qava_Add,
sup.Supplier_ID_Ekuep, supc.Supplier_Ekuep, supc.Supllier_City_Ekuep, supc.Supplier_Ekuep_Add
The output I am getting for Waybill_No = 43265104 is as follows, I just want to get rid of the null row.
WITH data(num, id) AS (
SELECT * FROM VALUES
(2559, 23),
(2559, 33),
(2559, 55),
(2550, 89),
(2499, 14),
(2499, 14)
)
SELECT
num,
id,
count(*) over(partition by num) as num_dup,
count(distinct id)over(partition by num) as id_dup,
iff(num_dup > 1 AND num_dup = id_dup, 1, 0) as "check"
FROM data;
gives:
NUM
ID
NUM_DUP
ID_DUP
check
2559
23
3
3
1
2559
33
3
3
1
2559
55
3
3
1
2550
89
1
1
0
2499
14
2
1
0
2499
14
2
1
0
Extra Data:
WITH data(num, id) AS (
SELECT * FROM VALUES
(2559, 23),
(2559, 33),
(2559, 33),
(2559, 55),
(2550, 89),
(2499, 14),
(2499, 14)
)
SELECT
num,
id,
count(*) over(partition by num) as num_dup,
count(distinct id)over(partition by num) as id_dup,
iff(num_dup > 1 AND num_dup = id_dup, 1, 0) as "check"
FROM data;
if we make 2559 have two 33's then it show change to 0/false
NUM
ID
NUM_DUP
ID_DUP
check
2559
23
4
3
0
2559
33
4
3
0
2559
33
4
3
0
2559
55
4
3
0
2550
89
1
1
0
2499
14
2
1
0
2499
14
2
1
0
Last Step:
WITH data(num, id) AS (
SELECT * FROM VALUES
(2559, 23),
(2559, 33),
(2559, 55),
(2550, 89),
(2499, 14),
(2499, 14)
)
SELECT
num,
iff(count(*) > 1 AND count(*) = count(distinct id), 1, 0) as output
FROM data
GROUP BY 1;
gives:
NUM
OUTPUT
2559
1
2550
0
2499
0
left join (
select
ID,
ORDER_ID,
WAYBILL_NO
from ORDER_WAYBILLS
) ow
on wb.WAYBILL_ID = ow.id
should just be:
LEFT JOIN order_waybills AS ow
ON wb.waybill_id = ow.id
Gaint Refactoing Starts Here
So I start refactoring this SQL, the first part was to ignore my prior "this could be simpler" and move that into a CTE ob_cte, so it was "just simple" then I notice the first two sections had large block you noted as op that where the same, so that becomes a CTE op_cte also then that gives us:
WITH ob_cte AS (
SELECT
id,
order_id,
waybill_no
FROM order_waybills
), op_etc AS (
SELECT
opr.id_order,
opr.id_product,
ss.id_supplier_ekuep,
ss.id_supplier_qava
FROM order_products AS opr
LEFT JOIN (
SELECT
s.id,
supc.id_supplier_ekuep,
supq.id_supplier_qava
FROM suppliers AS s
LEFT JOIN (
SELECT
id_supplier AS id_supplier_ekuep
FROM ekuep_ksa_ekuep_staging.ps_supplier
WHERE used_supplier_id IS NULL
) AS supc
ON supc.id_supplier_ekuep = s.id_supplier
AND s.store_id = 1
LEFT JOIN (
SELECT
id_supplier AS id_supplier_qava
FROM qavashop_ksa_qavaish_mainshop.ps_supplier
WHERE used_supplier_id IS NULL
) AS supq
ON supq.id_supplier_qava = s.id_supplier
AND s.store_id = 2
) AS ss
ON opr.SUPPLIER_ID = ss.ID
GROUP BY opr.id_order, opr.id_product, ss.id_supplier_ekuep, ss.id_supplier_qava
)
SELECT
wbd.waybill_id,
sup.waybill_no,
sup.supplier_id_qava,
supq.supplier_qava,
supq.supllier_city_qava,
supq.supplier_qava_add,
sup.supplier_id_ekuep,
supc.supplier_ekuep,
supc.supllier_city_ekuep,
supc.supplier_ekuep_add
FROM waybill_products AS wbd
LEFT JOIN (
SELECT
wb.waybill_id,
ow.waybill_no,
CASE
WHEN mult.multi_supp_qava = 1 THEN '1'
WHEN mult.multi_supp_qava = 0 THEN op.ID_Supplier_Qava
ELSE NULL
end as supplier_id_qava,
case
WHEN mult.multi_supp_ekuep = 1 THEN '1'
WHEN mult.multi_supp_ekuep = 0 THEN op.ID_Supplier_Ekuep
ELSE NULL
END AS supplier_id_ekuep
FROM waybill_products AS wb
LEFT JOIN ob_cte AS ow
ON wb.waybill_id = ow.id
LEFT JOIN op_etc AS op
ON op.id_product = wb.product_id
AND op.id_order = ow.order_id
------------------------------------------------------------------------------------------------------------------------
left join (
select
wb.WAYBILL_ID,
ow.WAYBILL_NO,
(count(distinct op.ID_Supplier_Qava) > 1)::int as multi_supp_qava,
(count(distinct op.ID_Supplier_Ekuep) > 1)::int as multi_supp_ekuep
from WAYBILL_PRODUCTS wb
LEFT JOIN ob_cte AS ow
ON wb.waybill_id = ow.id
left join op_etc AS op
on op.ID_PRODUCT = wb.PRODUCT_ID
and op.ID_ORDER = ow.ORDER_ID
where _FIVETRAN_DELETED = 0
group by wb.WAYBILL_ID, ow.WAYBILL_NO
) AS mult
on mult.WAYBILL_NO = ow.WAYBILL_NO
------------------------------------------------------------------------------------------------------------------------
group by wb.WAYBILL_ID, ow.WAYBILL_NO, mult.multi_supp_qava, mult.multi_supp_ekuep, op.ID_Supplier_Qava, op.ID_Supplier_Ekuep
) AS sup
on wbd.WAYBILL_ID = sup.WAYBILL_ID
left join (
select
ps.id_supplier AS id_supplier_qava,
ps.name AS supplier_qava,
ps.date_add AS supplier_qava_add,
LISTAGG(DISTINCT pa.CITY, ', ') AS supllier_city_qava
from QAVASHOP_KSA_QAVAISH_MAINSHOP.PS_SUPPLIER ps
left join (
select *
from QAVASHOP_KSA_QAVAISH_MAINSHOP.PS_ADDRESS
) pa
ON pa.ID_SUPPLIER = ps.ID_SUPPLIER
AND pa._fivetran_deleted = 0
WHERE ps.USED_SUPPLIER_ID is null
AND ps._fivetran_deleted = 0
GROUP BY 1, 2, 3
) AS supq
on supq.ID_Supplier_Qava = sup.Supplier_ID_Qava
left join (
select
ps.id_supplier AS id_supplier_ekuep,
ps.name AS supplier_ekuep,
ps.date_add AS supplier_ekuep_add,
LISTAGG(DISTINCT pa.CITY, ', ') AS supllier_city_ekuep
FROM ekuep_ksa_ekuep_staging.ps_supplier AS ps
LEFT JOIN FROM ekuep_ksa_ekuep_staging.ps_address AS pa
ON pa.id_supplier = ps.id_supplier
and pa._fivetran_deleted = 0
WHERE ps.used_supplier_id IS NULL
and ps._fivetran_deleted = 0
GROUP BY 1, 2, 4
) AS supc
ON supc.id_supplier_ekuep = sup.supplier_id_ekuep
WHERE _fivetran_deleted = 0
GROUP BY wbd.waybill_id, sup.waybill_no,
sup.supplier_id_qava, supq.supplier_qava,
supq.supllier_city_qava, supq.supplier_qava_add,
sup.supplier_id_ekuep, supc.supplier_ekuep,
supc.supllier_city_ekuep, supc.supplier_ekuep_add;
Now op_etc itself, that GROUP BY at the end is really just a DISTINCT so we can swap that in. Also in ss of that op_cte
SELECT
s.id,
supc.id_supplier_ekuep,
supq.id_supplier_qava
FROM suppliers AS s
LEFT JOIN (
SELECT
id_supplier AS id_supplier_ekuep
FROM ekuep_ksa_ekuep_staging.ps_supplier
WHERE used_supplier_id IS NULL
) AS supc
ON supc.id_supplier_ekuep = s.id_supplier
AND s.store_id = 1
LEFT JOIN (
SELECT
id_supplier AS id_supplier_qava
FROM qavashop_ksa_qavaish_mainshop.ps_supplier
WHERE used_supplier_id IS NULL
) AS supq
ON supq.id_supplier_qava = s.id_supplier
AND s.store_id = 2
those to left joins, keep only values that are NULL and then LEFT JOIN of two requirements which means we are get a row per suppliers the IS NULL can be moved to the ON with no impact, which means the rename can be moved higher up, and the sub-select dropped, so that section can become:
SELECT
s.id,
supc.id_supplier AS id_supplier_ekuep,
supq.id_supplier AS id_supplier_qava
FROM suppliers AS s
LEFT JOIN ekuep_ksa_ekuep_staging.ps_supplier AS supc
ON supc.id_supplier = s.id_supplier
AND s.store_id = 1
AND supc.used_supplier_id IS NULL
LEFT JOIN qavashop_ksa_qavaish_mainshop.ps_supplier AS supq
ON supq.id_supplier = s.id_supplier
AND s.store_id = 2
AND supq.used_supplier_id IS NULL
thus the op_cte becomes:
), op_etc AS (
SELECT DISTINCT
opr.id_order,
opr.id_product,
ss.id_supplier_ekuep,
ss.id_supplier_qava
FROM order_products AS opr
LEFT JOIN (
SELECT
s.id,
supc.id_supplier AS id_supplier_ekuep,
supq.id_supplier AS id_supplier_qava
FROM suppliers AS s
LEFT JOIN ekuep_ksa_ekuep_staging.ps_supplier AS supc
ON supc.id_supplier = s.id_supplier
AND s.store_id = 1
AND supc.used_supplier_id IS NULL
LEFT JOIN qavashop_ksa_qavaish_mainshop.ps_supplier AS supq
ON supq.id_supplier = s.id_supplier
AND s.store_id = 2
AND supq.used_supplier_id IS NULL
) AS ss
ON opr.SUPPLIER_ID = ss.ID
)
which actually means the ss can just be left joined as first order things like:
), op_etc AS (
SELECT DISTINCT
opr.id_order,
opr.id_product,
supc.id_supplier AS id_supplier_ekuep,
supq.id_supplier AS id_supplier_qava
FROM order_products AS opr
LEFT JOIN suppliers AS s
opr.SUPPLIER_ID = s.ID
LEFT JOIN ekuep_ksa_ekuep_staging.ps_supplier AS supc
ON supc.id_supplier = s.id_supplier
AND s.store_id = 1
AND supc.used_supplier_id IS NULL
LEFT JOIN qavashop_ksa_qavaish_mainshop.ps_supplier AS supq
ON supq.id_supplier = s.id_supplier
AND s.store_id = 2
AND supq.used_supplier_id IS NULL
)
ah thats much more refreshing..
in the sub-select sup` I am worried, that you are grouping by values that are not in you output set, so you will get duplicate rows
in this case block
CASE
WHEN mult.multi_supp_qava = 1 THEN '1'
WHEN mult.multi_supp_qava = 0 THEN op.ID_Supplier_Qava
ELSE NULL
end as supplier_id_qava,
you are group not by the output supplier_id_qava or it's position 3 but mult.multi_supp_qava, op.ID_Supplier_Qava
so if op.ID_Supplier_Qava is not null when mult.multi_supp_qava = 1 and can have different values, the supplier_id_qava will output 1 on both rows, but they will not merge, as op.ID_Supplier_Qava is different. This is the root of my strong dislike for using the input to the SELECT section as the grouping clauses of the aggregation of those values. because through transformation, they can become the same on the output, but remain different on the input, and produce hard to debug deuplicates. And if the flip case that they are alway safe/null/constant in the odd case, this is not clear to the SQL reader. (on this point I have to say a strong thank you for have used the aliases on select etc, as that alway confidance of where those values are coming from).
So again the GROUP BY on sup has no agration of values so this is a hidden DISTINCT, but it not giving distinct values perhaps in all cases.
So after moving some sub-selects into CTE's as I find it makes each select layer show, just what it is doing, with have to leap over smaller details we get SQL like this:
WITH ob_cte AS (
SELECT
id,
order_id,
waybill_no
FROM order_waybills
), op_etc AS (
SELECT DISTINCT
opr.id_order,
opr.id_product,
supc.id_supplier AS id_supplier_ekuep,
supq.id_supplier AS id_supplier_qava
FROM order_products AS opr
LEFT JOIN suppliers AS s
opr.SUPPLIER_ID = s.ID
LEFT JOIN ekuep_ksa_ekuep_staging.ps_supplier AS supc
ON supc.id_supplier = s.id_supplier
AND s.store_id = 1
AND supc.used_supplier_id IS NULL
LEFT JOIN qavashop_ksa_qavaish_mainshop.ps_supplier AS supq
ON supq.id_supplier = s.id_supplier
AND s.store_id = 2
AND supq.used_supplier_id IS NULL
), mult_cte AS (
SELECT
wb.waybill_id,
ow.waybill_no,
(COUNT(DISTINCT op.id_supplier_qava) > 1)::int AS multi_supp_qava,
(COUNT(DISTINCT op.id_supplier_ekuep) > 1)::int AS multi_supp_ekuep
FROM waybill_products AS wb
LEFT JOIN ob_cte AS ow
ON wb.waybill_id = ow.id
LEFT JOIN op_etc AS op
ON op.id_product = wb.product_id
AND op.id_order = ow.order_id
WHERE _fivetran_deleted = 0
GROUP BY wb.waybill_id, ow.waybill_no
), supq_cte AS (
SELECT
ps.id_supplier AS id_supplier_qava,
ps.name AS supplier_qava,
ps.date_add AS supplier_qava_add,
LISTAGG(DISTINCT pa.city, ', ') AS supllier_city_qava
FROM qavashop_ksa_qavaish_mainshop.ps_supplier AS ps
LEFT JOIN qavashop_ksa_qavaish_mainshop.ps_address AS pa
ON pa.id_supplier = ps.id_supplier
AND pa._fivetran_deleted = 0
WHERE ps.used_supplier_id is null
AND ps._fivetran_deleted = 0
GROUP BY 1, 2, 3
), supc_cte AS (
SELECT
ps.id_supplier AS id_supplier_ekuep,
ps.name AS supplier_ekuep,
ps.date_add AS supplier_ekuep_add,
LISTAGG(DISTINCT pa.city, ', ') AS supllier_city_ekuep
FROM ekuep_ksa_ekuep_staging.ps_supplier AS ps
LEFT JOIN FROM ekuep_ksa_ekuep_staging.ps_address AS pa
ON pa.id_supplier = ps.id_supplier
AND pa._fivetran_deleted = 0
WHERE ps.used_supplier_id IS NULL
AND ps._fivetran_deleted = 0
GROUP BY 1, 2, 4
), sup_cte AS (
SELECT DISTINCT
wb.waybill_id,
ow.waybill_no,
CASE
WHEN mult.multi_supp_qava = 1 THEN '1'
WHEN mult.multi_supp_qava = 0 THEN op.ID_Supplier_Qava
ELSE NULL
end as supplier_id_qava,
case
WHEN mult.multi_supp_ekuep = 1 THEN '1'
WHEN mult.multi_supp_ekuep = 0 THEN op.ID_Supplier_Ekuep
ELSE NULL
END AS supplier_id_ekuep
FROM waybill_products AS wb
LEFT JOIN ob_cte AS ow
ON wb.waybill_id = ow.id
LEFT JOIN op_etc AS op
ON op.id_product = wb.product_id
AND op.id_order = ow.order_id
------------------------------------------------------------------------------------------------------------------------
LEFT JOIN mult_cte AS mult
on mult.WAYBILL_NO = ow.WAYBILL_NO
------------------------------------------------------------------------------------------------------------------------
)
SELECT
wbd.waybill_id,
sup.waybill_no,
sup.supplier_id_qava,
supq.supplier_qava,
supq.supllier_city_qava,
supq.supplier_qava_add,
sup.supplier_id_ekuep,
supc.supplier_ekuep,
supc.supllier_city_ekuep,
supc.supplier_ekuep_add
FROM waybill_products AS wbd
LEFT JOIN sup_cte AS sup
ON wbd.WAYBILL_ID = sup.WAYBILL_ID
LEFT JOIN supq_cte AS supq
ON supq.id_supplier_qava = sup.supplier_id_qava
LEFT JOIN supc_cte AS supc
ON supc.id_supplier_ekuep = sup.supplier_id_ekuep
WHERE _fivetran_deleted = 0
GROUP BY wbd.waybill_id, sup.waybill_no,
sup.supplier_id_qava, supq.supplier_qava,
supq.supllier_city_qava, supq.supplier_qava_add,
sup.supplier_id_ekuep, supc.supplier_ekuep,
supc.supllier_city_ekuep, supc.supplier_ekuep_add;
And at the end we see again you are suffering from duplicate data, that you are trying to clean away with yet another GROUP BY.. so we will switch to a DISTINCT
SELECT DISTINCT
wbd.waybill_id,
sup.waybill_no,
sup.supplier_id_qava,
supq.supplier_qava,
supq.supllier_city_qava,
supq.supplier_qava_add,
sup.supplier_id_ekuep,
supc.supplier_ekuep,
supc.supllier_city_ekuep,
supc.supplier_ekuep_add
FROM waybill_products AS wbd
LEFT JOIN sup_cte AS sup
ON wbd.WAYBILL_ID = sup.WAYBILL_ID
LEFT JOIN supq_cte AS supq
ON supq.id_supplier_qava = sup.supplier_id_qava
LEFT JOIN supc_cte AS supc
ON supc.id_supplier_ekuep = sup.supplier_id_ekuep
WHERE _fivetran_deleted = 0
Right so what was your question again?
you want to get rid of all the nulls... if this is so "why so many left joins" or returning null from CASE statements..
Right so in the picture to show a waybill_no with values, and another where supplier_id_qava is null, given the later comes from
LEFT JOIN sup_cte AS sup
ON wbd.WAYBILL_ID = sup.WAYBILL_ID
and everything else connect via sup you should change that from a LEFT JOIN to just a JOIN

Flattened SQL query

This is in SQL Server 2014.
Without changing the table structures what is the easiest way you can suggest to change this query (output shown below)
select
a.Id, a.Sku, a.lbl,
Desc,
(select b.Valu where b.Attribute = 'rel') as 'rel',
(select b.Valu where b.Attribute = 'uom') as 'uom',
(select b.Valu where b.Attribute = 'clas') as 'clas'
from
items a
join
itemattributes b on b.id = a.id
Output:
id sku lbl desc rel uom clas
2 X111 X111-456789 red NULL NULL C
2 X111 X111-456789 red NULL Cs NULL
2 X111 X111-456789 red 3 NULL NULL
3 X222 X222-567890 white NULL NULL B
3 X222 X222-567890 white NULL Cs NULL
3 X222 X222-567890 white 2 NULL NULL
4 X333 X333-678901 blue NULL NULL C
4 X333 X333-678901 blue NULL Ea NULL
4 X333 X333-678901 blue 9 NULL NULL
To this output:
id sku lbl desc rel uom clas
2 X111 X111-456789 red 3 Cs C
3 X222 X222-567890 white 2 Cs B
4 X333 X333-678901 blue 9 Ea C
You can use conditional aggregation to group by different attribute values.
select a.Id
, a.Sku
, a.lbl
, [Desc]
, max(case when b.Attribute = 'rel' then b.Valu end) as rel
, max(case when b.Attribute = 'uom' then b.Valu end) as uom
, max(case when b.Attribute = 'clas' then b.Valu end) as clas
from items a
join itemattributes b
on b.id = a.id
group by a.Id
, a.Sku
, a.lbl
, [Desc]
You could try:
select a.Id
, a.Sku
, a.lbl
, Desc
, rel.Valu as 'rel'
, uom.Valu as 'uom'
, clas.Valu as 'clas'
from items a
join itemattributes rel
on rel.id = a.id and rel.Attribute = 'rel'
join itemattributes uom
on uom.id = a.id and uom.Attribute = 'uom'
join itemattributes clas
on clas.id = a.id and clas.Attribute = 'clas'
This assumes you will only want records that have all three values. If this is not a true assumption, try left joins. Note I put the attribute in the join to make it easier if you have to use a left join. if you use inner joins then you could put those in the where clause.
You could do multiple joins:
select a.Id
, a.Sku
, a.lbl
, Desc
, b.Valu as 'rel'
, c.Valu as 'uom'
, d.Valu as 'clas'
from items a
join itemattributes b on b.id = a.id
join itemattributes c on c.id = a.id
join itemattributes d on d.id = a.id
where b.Attribute = 'rel'
and c.Attribute = 'uom'
and d.Attribute = 'clas'
You should also be able to eliminate the joins altogether:
select a.Id
, a.Sku
, a.lbl
, Desc
, (select b.Valu from itemattributes b where b.id = a.id and b.Attribute = 'rel') as 'rel'
, (select b.Valu from itemattributes b where b.id = a.id and b.Attribute = 'uom') as 'uom'
, (select b.Valu from itemattributes b where b.id = a.id and b.Attribute = 'clas') as 'clas'
from items a

SQL how to get previous record if dis_stat = 20

I am trying to get records that if they meet a certain condition then do not get included in the records. I can get all the records i need but when i try to then group records based on trying to eliminate that record combo i am not sure how to do that. If dis_stat = 20 then do not show that record and previous record.
Example records:
MEMBER : Readmit_conf_30 : Conf_num : Dis_Stat
12345 1212 6
12345 1213 6
12345 1215 1214 1
12345 1216 1215 7
12345 1216 20
So the conf_num = 1216 with dis_stat = 20 should not show along with previous record of conf_num= 1215, readmit_conf_30 = 1216
Here is code i have to get records for this member. I have tried many ways get rid of those 2 records but no success.
Thanks for the help.
Code:
WITH Group1 AS (
SELECT A.MEMBER, B.SEX, B.DOB, B.LAST_NAME, B.FIRST_NAME, A.PROVIDER_ID, C.PROVIDER_NAME
, A.CONF_NUM, A.BEG_DT, A.END_DT, A.TOS_I_4, A.DIS_STAT, A.AMT_EQV, A.AMT_PAY, A.AMT_REQ
, A.READMIT_INDEX_30, A.READMIT_30, A.READMIT_CONF_30
FROM CONFINEMENTS A
LEFT JOIN MEMINFO B ON A.MEMBER = B.MEMBER
LEFT JOIN PROVINFO C ON A.PROVIDER_ID = C.PROVIDER_ID
LEFT JOIN MAP_DATE_RANGE D ON D.IA_TIME = A.IA_TIME
WHERE A.CUST_OPL_MED IN ('A$*', 'B$*', 'N$*', 'P$*', 'D$*', 'Unspecified$UNK')
--AND A.BEG_DT >= '05/01/2013' and A.beg_dt <'05/01/2014'
and A.PROVIDER_ID Like '344428218046' --firelands regional
and (A.READMIT_30 = 1 OR A.READMIT_30 = 0)
--AND A.DIS_STAT <> 20
AND A.MEMBER = '03732529500' --'04644786700'
),
GROUP2 AS (
SELECT AA.MEMBER, AA.READMIT_CONF_30
FROM Group1 AA
WHERE AA.READMIT_CONF_30 > 0
--AND AA.DIS_STAT <> 20
),
select MEMBER, READMIT_CONF_30
,SEX, DOB, LAST_NAME, FIRST_NAME, PROVIDER_ID, PROVIDER_NAME
, CONF_NUM, BEG_DT, END_DT, TOS_I_4, DIS_STAT, AMT_EQV, AMT_PAY, AMT_REQ
, READMIT_30, READMIT_INDEX_30
from group1
union
select MEMBER, READMIT_CONF_30
,SEX, DOB, LAST_NAME, FIRST_NAME, PROVIDER_ID, PROVIDER_NAME
, CONF_NUM, BEG_DT, END_DT, TOS_I_4, DIS_STAT, AMT_EQV, AMT_PAY, AMT_REQ
, READMIT_30, READMIT_INDEX_30
from Group3
order by conf_num
You should be able to use NOT EXISTS().. though with the code sample you provided it's hard to tell exactly where.. but in your first cte GROUP1 it would look like
WHERE
----
AND a.Dis_Stat <> 20
AND NOT EXISTS (SELECT 1
FROM CONFINEMENTS c
WHERE c.Conf_num = a.Readmit_conf_30
AND c.Dis_Stat = 20)

MSSQL - 2 Tables with multiple rows merge in one table

I have 2 selects which returns 2 tables, in each table I have 12 rows, and 2 column, now I want to have just one table.
---- First Table
select f. date as Date, f.value as Month1
from
(
select b.date as date, sum(b.value) as value
from business bu
join bus_cat buc on buc.id = bu.id
join cat ct on ct.id = buc.type_id
join bus2 b on b.id = buc.id
where ct.id = 1
and b.value <> 0
and b.date between #start and #actual
and bu.name = #bu_name
group by b.date, b.value
union all
select b5.date as date, sum(b5.value) as value
from bus bu
join bus_cat buc on buc.id = bu.id
join cat ct on ct.id = buc.type_id
join bus3 b5 on b5.id = buc.id
where ct.id = 1
and b5.value <> 0
and b5.date between #nextM and #endM
and bu.name = #bu_name
group by b5.date, b5.value
) as f
---- Second Table
select f1. date as Date, f1.value as Month2
from
(
select b.date as date, sum(b.value) as value
from business bu
join bus_cat buc on buc.id = bu.id
join cat ct on ct.id = buc.type_id
join bus2 b on b.id = buc.id
where ct.id = 1
and b.value <> 0
and b.date between #start and #actual
and bu.name = #bu_name
group by b.date, b.value
union all
select b5.date as date, sum(b5.value) as value
from bus bu
join bus_cat buc on buc.id = bu.id
join cat ct on ct.id = buc.type_id
join bus3 b5 on b5.id = buc.id
where ct.id = 1
and b5.value <> 0
and b5.date between #nextM and #endM
and bu.name = #bu_name
group by b5.date, b5.value
) as f1
The actual output for first table is:
Date Month1
2015-01-01 23
2015-01-01 77
and for second:
Date Month2
2015-01-01 88
2015-01-01 90
All I want is to merge this 2 tables to look like
Date Month1 Date Month2
2015-01-01 23 2015-01-01 77
2015-01-01 28 2015-01-01 787
As I said in my comment, a simple join should do the trick. Something like:
SELECT *
FROM
(
select b.date as date, sum(b.value) as value
from business bu
join bus_cat buc on buc.id = bu.id
join cat ct on ct.id = buc.type_id
join bus2 b on b.id = buc.id
where ct.id = 1
and b.value <> 0
and b.date between #start and #actual
and bu.name = #bu_name
group by b.date, b.value
union all
select b5.date as date, sum(b5.value) as value
from bus bu
join bus_cat buc on buc.id = bu.id
join cat ct on ct.id = buc.type_id
join bus3 b5 on b5.id = buc.id
where ct.id = 1
and b5.value <> 0
and b5.date between #nextM and #endM
and bu.name = #bu_name
group by b5.date, b5.value
) as f
LEFT JOIN (
select b.date as date, sum(b.value) as value
from business bu
join bus_cat buc on buc.id = bu.id
join cat ct on ct.id = buc.type_id
join bus2 b on b.id = buc.id
where ct.id = 1
and b.value <> 0
and b.date between #start and #actual
and bu.name = #bu_name
group by b.date, b.value
union all
select b5.date as date, sum(b5.value) as value
from bus bu
join bus_cat buc on buc.id = bu.id
join cat ct on ct.id = buc.type_id
join bus3 b5 on b5.id = buc.id
where ct.id = 1
and b5.value <> 0
and b5.date between #nextM and #endM
and bu.name = #bu_name
group by b5.date, b5.value
) as f1
ON f.date = f1.date
edit
By the way, this query can be simplified, looks like there are many similarities in the queries.

How to join result of two sql statements into one table and different columns

I have three select queries which return total records , succesful records and failure records from same table based on different where clauses . I want to join the result of all these statements into one table in order to make my stored procedure but the resulting table shall have three different columns for cdr , success , failure
SELECT Count(*) AS cdr
FROM ABC AS c WITH (NOLOCK)
WHERE APPID IN( 1, 2 )
AND CALLDATE = '2012-10-09'
SELECT Count(*) AS success
FROM ABC AS d WITH (NOLOCK)
WHERE APPID IN( 44, 45 )
AND CALLDATE = '2012-10-09'
AND HANGUPCODE IN ( 'man', 'mach' )
SELECT Count(*) AS fail
FROM ABC WITH (NOLOCK)
WHERE APPID IN( 44, 45 )
AND CALLDATE = '2012-10-09'
AND HANGUPCODE NOT IN ( 'man', 'mach' )
Union gives out the result in one column so it won't work . any other ideas
Just wrap each select statement in parentheses, give each select statement an alias, and use SELECT at the top:
SELECT
(select count(*) as cdr
from abc as c with (nolock)
where appid in(1,2) and calldate = '2012-10-09'
) AS Column1,
(select count(*) as success
from abc as d with (nolock)
where appid in(44,45) and calldate = '2012-10-09'
and hangupcode in ('man', 'mach')
) AS Column2,
(select count(*) as fail
from abc with (nolock)
where appid in(44,45) and calldate = '2012-10-09'
and hangupcode not in ('man', 'mach')
) AS Column3
Basically you're treating each query as an individual column.
SELECT a.cdr, b.success, c.failure FROM
(SELECT count(*) AS cdr
FROM abc as c WITH (NOLOCK)
WHERE appid IN (1,2) AND
calldate = '2012-10-09'
) AS a,
(SELECT count(*) AS success
FROM abc AS d WITH (NOLOCK)
WHERE appid IN (44,45) AND
calldate = '2012-10-09' AND
hangupcode IN ('man', 'mach')
) AS b,
(SELECT count(*) AS fail
FROM abc WITH (NOLOCK)
WHERE appid IN (44,45) AND
calldate = '2012-10-09' AND
hangupcode NOT IN ('man', 'mach')
) AS c
select a.cdr, b.success, c.fail from
( select count(*) as cdr
from abc as c with (nolock) where appid in(1,2)
and calldate = '2012-10-09' ) a
, ( select count(*) as success
from abc as d with (nolock) where appid in(44,45)
and calldate = '2012-10-09'
and hangupcode in ('man', 'mach') ) b
, ( select count(*) as fail from abc with (nolock) where appid in(44,45) and calldate = '2012-10-09'and hangupcode not in ('man', 'mach') ) c
select
sum(case when appid in(1,2) and calldate = '2012-10-09' then 1 else 0 end) as cdr,
sum(case when appid in(44,45) and calldate = '2012-10-09'and hangupcode in ('man', 'mach') then 1 else 0 end) as success,
sum(case when appid in(44,45) and calldate = '2012-10-09'and hangupcode not in ('man', 'mach') then 1 else 0 end)as fail
from abc