sql count new id that did not exists before for each month - sql

I have the follow set of data
enter image description here
how can I write the sql to gives the result on right side?
that is the counting of unique id that did appeared previously for each month.

After long time of reading and reading his question, Ssiu wanted to ask the following:
So here is the test data in MS SQL: at that time he didn't clarify on postgresql
create table tmp1 (
ddate datetime
, iid int
)
insert into tmp1 values
('2017-11-01',1)
,('2017-11-02',2)
,('2017-11-03',3)
,('2017-11-04',4)
,('2017-11-05',5)
,('2017-11-06',5)
,('2017-11-07',5)
,('2017-12-01',1)
,('2017-12-02',2)
,('2017-12-03',3)
,('2017-12-04',6)
,('2017-12-05',7)
,('2018-01-01',1)
,('2018-01-02',2)
,('2018-01-03',3)
,('2018-01-04',4)
,('2018-01-05',8)
Disclaimer: The following is not the best approach for this problem. It is not applicable for more months, however it can give Ssiu a clue.
with cte(mmonth, iid) as (
select distinct convert(varchar(7), ddate, 120) mmonth
, iid
from tmp1
)
, cte_201711 as (
select * from cte where mmonth = '2017-11'
)
, cte_201712 as (
select * from cte where mmonth = '2017-12'
)
, cte_201801 as (
select * from cte where mmonth = '2018-01'
)
, cte_cnt201712 as(
select cte_201711.mmonth as mm201711
, cte_201711.iid as id201711
, cte_201712.mmonth as mm201712
, cte_201712.iid as id201712
from cte_201711
full outer join cte_201712
on cte_201712.iid = cte_201711.iid
)
, cte_cnt201801 as (
select cte_201711.mmonth as mm201711
, cte_201711.iid as id201711
, cte_201712.mmonth as mm201712
, cte_201712.iid as id201712
, cte_201801.mmonth as mm201801
, cte_201801.iid as id201801
from cte_201711
full outer join cte_201712
on cte_201712.iid = cte_201711.iid
full outer join cte_201801
on cte_201801.iid = cte_201712.iid
or cte_201801.iid = cte_201711.iid
)
--select * from cte_cnt201801 order by isnull(mm201711,'z'), isnull(mm201712,'z')
select '2017-12' mmonth, count(*) Ssiu
from cte_cnt201712
where mm201711 is null
union all
select '2018-01' mmonth, count(*) Ssiu
from cte_cnt201801
where mm201711 is null
and mm201712 is null
Note the data for the cte_cnt201801 CTE:
select * from cte_cnt201801 order by isnull(mm201711,'z'), isnull(mm201712,'z')
So the result for the above query is:

Related

how to delete repeated values in UNION query using count

Hello I have been trying to delete a repeated value on the following UNION query with the following results (image). How can I filter out the value LW_ID=8232 with AANTALLN =0. I need to find a way taht if in the first query AANTALLN >0 is found, then on the second part of the union query not insert it again. Thanks "
With LESEENHEIDLOOPBAAN as (
SELECT
LE_AGENDA_FK,
LE_CODE,
LE_ID,
LE_KLAS_FK,
LE_KLASPARTITIE_FK,
LE_OMSCHRIJVING,
LE_VERANDERDDOOR,
LE_VERANDERDOP,
Count(LH_ID) As AantalLln
FROM
LESEENHEID
INNER JOIN LOOPBAANLESEENHEID on (LH_LESEENHEID_FK = LE_ID)
INNER JOIN LOOPBAAN ON (LH_LOOPBAAN_FK = LB_ID)
WHERE
(
'2022/09/28' BETWEEN LB_VAN
AND LB_TOT
)
AND (
LE_ID in (8277, 8276, 8232)
)
GROUP BY
LE_AGENDA_FK,
LE_CODE,
LE_ID,
LE_KLAS_FK,
LE_KLASPARTITIE_FK,
LE_OMSCHRIJVING,
LE_VERANDERDDOOR,
LE_VERANDERDOP
),
LESEENHEIDLOOPBAANNULL AS (
SELECT
LE_AGENDA_FK,
LE_CODE,
LE_ID,
LE_KLAS_FK,
LE_KLASPARTITIE_FK,
LE_OMSCHRIJVING,
LE_VERANDERDDOOR,
LE_VERANDERDOP,
0 As AantalLln
FROM
LESEENHEID
where
LE_ID in (8277, 8276, 8232)
and EXISTS (
SELECT
*
FROM
LESEENHEIDLOOPBAAN
)
)
SELECT
*
FROM
LESEENHEIDLOOPBAAN
UNION
SELECT
*
FROM
LESEENHEIDLOOPBAANNULL ROWS 1000
Try this out using ROW_NUMBER:
SELECT * FROM (
SELECT
ROW_NUMBER () OVER (PARTITION BY LW_ID ORDER BY AANTALLN DESC) AS RN
,* FROM
(
SELECT * FROM
LESEENHEIDLOOPBAAN
UNION
SELECT
*
FROM
LESEENHEIDLOOPBAANNULL ROWS 1000
)
)
) WHERE RN = 1
This way you eliminate the duplicates.

Where should i put the AS Clause for tax rate (VAT_RATE)

I want to put a AS VAT_RATE in this SELECT statement but i don't know where.
SELECT ROW_NUMBER() OVER(ORDER BY QD.DETAIL_ID) AS No,
QD.PRODUCT_ID AS PROD_ID,PM.'+#ProdCode+' AS PROD_CODE,pm.DESCRIPTION AS SHORT_DESC,
QD.CORPORATE_PRICE AS Corpo_Price,CONVERT(DECIMAL(18,2),QD.RETAIL_PRICE) AS UNIT_SP,QD.COST_PRICE AS COST_SP,
QD.GM,QD.DETAIL_ID,QD.DISC AS Discount,QD.NOTE,
VAT_RATE=(SELECT VAT_RATE/100 FROM dbo.vat
WHERE VAT_ID=(SELECT TOP 1 VAT_ID FROM dbo.product_detail(NOLOCK) WHERE PRODUCT_ID=PM.PROD_ID))
,
Img=(SELECT TOP 1 IMAGE_DATA FROM dbo.PRODUCT_IMAGE WHERE PRODUCT_ID=PM.PROD_ID), QD.CostPrice_Percentage
FROM dbo.CUSTOMER_QUOTATION_DETAIL(NOLOCK) QD
JOIN dbo.product_master(NOLOCK) PM ON PM.PROD_ID=QD.PRODUCT_ID
In TSQL you there is 3 way to name your columns
1) With the AS (optional in tsql)
SELECT QD.PRODUCT_ID AS PROD_ID
FROM dbo.CUSTOMER_QUOTATION_DETAIL(NOLOCK) QD
2) Without the AS (since it is optional)
SELECT QD.PRODUCT_ID PROD_ID
FROM dbo.CUSTOMER_QUOTATION_DETAIL(NOLOCK) QD
3) with an equal sign as if it is a formula
SELECT PROD_ID = QD.PRODUCT_ID
FROM dbo.CUSTOMER_QUOTATION_DETAIL(NOLOCK) QD
Specifically for your query this is where the AS should go.
You would have to remove the equal and put the AS at the end of the sub-query.
Please do note that you have various other issues with the queries that is beyond the scope your original question. If you run into preformance issue, do investigated on the subject of CROSS APPLY / CROSS OUTER JOIN and/or CTE : Common Table Expression.
SELECT ROW_NUMBER() OVER (
ORDER BY QD.DETAIL_ID
) AS No
, QD.PRODUCT_ID AS PROD_ID
--, PM.'+#ProdCode+' AS PROD_CODE
, #ProdCode AS PROD_CODE
, pm.DESCRIPTION AS SHORT_DESC
, QD.CORPORATE_PRICE AS Corpo_Price
, CONVERT(DECIMAL(18, 2), QD.RETAIL_PRICE) AS UNIT_SP
, QD.COST_PRICE AS COST_SP
, QD.GM
, QD.DETAIL_ID
, QD.DISC AS Discount
, QD.NOTE
, (
SELECT TOP 1 (VAT_RATE / 100)
FROM dbo.vat
WHERE VAT_ID = (
SELECT TOP 1 VAT_ID
FROM dbo.product_detail(NOLOCK)
WHERE PRODUCT_ID = PM.PROD_ID
)
) AS VAT_RATE
, (
SELECT TOP 1 IMAGE_DATA
FROM dbo.PRODUCT_IMAGE
WHERE PRODUCT_ID = PM.PROD_ID
) AS Img
, QD.CostPrice_Percentage
FROM dbo.CUSTOMER_QUOTATION_DETAIL(NOLOCK) QD
JOIN dbo.product_master(NOLOCK) PM
ON PM.PROD_ID = QD.PRODUCT_ID

How to merge two columns from CASE STATEMENT of DIFFERENT CONDITION

My expected result should be like
----invoiceNo----
T17080003,INV14080011
But right now, I've come up with following query.
SELECT AccountDoc.jobCode,AccountDoc.shipmentSyskey,AccountDoc.docType,
CASE AccountDoc.docType
WHEN 'M' THEN
JobInvoice.invoiceNo
WHEN 'I' THEN
(STUFF((SELECT ', ' + RTRIM(CAST(AccountDoc.docNo AS VARCHAR(20)))
FROM AccountDoc LEFT OUTER JOIN JobInvoice
ON AccountDoc.principalCode = JobInvoice.principalCode AND
AccountDoc.jobCode = JobInvoice.jobCode
WHERE (AccountDoc.isCancelledByCN = 0)
AND (AccountDoc.docType = 'I')
AND (AccountDoc.jobCode = #jobCode)
AND (AccountDoc.shipmentSyskey = #shipmentSyskey)
AND (AccountDoc.principalCode = #principalCode) FOR XML
PATH(''), TYPE).value('.','NVARCHAR(MAX)'),1,2,' '))
END AS invoiceNo
FROM AccountDoc LEFT OUTER JOIN JobInvoice
ON JobInvoice.principalCode = AccountDoc.principalCode AND
JobInvoice.jobCode = AccountDoc.jobCode
WHERE (AccountDoc.jobCode = #jobCode)
AND (AccountDoc.isCancelledByCN = 0)
AND (AccountDoc.shipmentSyskey = #shipmentSyskey)
AND (AccountDoc.principalCode = #principalCode)
OUTPUT:
----invoiceNo----
T17080003
INV14080011
Explanation:
I want to select docNo from table AccountDoc if AccountDoc.docType = I.
Or select invoiceNo from table JobInvoice if AccountDoc.docType = M.
The problem is what if under same jobCode there have 2 docType which are M and I, how I gonna display these 2 invoices?
You can achieve this by using CTE and FOR XML. below is the sample code i created using similar tables you have -
Create table #AccountDoc (
id int ,
docType char(1),
docNo varchar(10)
)
Create table #JobInvoice (
id int ,
invoiceNo varchar(10)
)
insert into #AccountDoc
select 1 , 'M' ,'M1234'
union all select 2 , 'M' ,'M2345'
union all select 3 , 'M' ,'M3456'
union all select 4 , 'I' ,'I1234'
union all select 5 , 'I' ,'I2345'
union all select 6 , 'I' ,'I3456'
insert into #JobInvoice
select 1 , 'INV1234'
union all select 2 , 'INV2345'
union all select 3 , 'INV3456'
select *
from #AccountDoc t1 left join #JobInvoice t2
on t1.id = t2.id
with cte as
(
select isnull( case t1.docType WHEN 'M' THEN t2.invoiceNo WHEN 'I' then
t1.docNo end ,'') invoiceNo
from #AccountDoc t1 left join #JobInvoice t2
on t1.id = t2.id )
select invoiceNo + ',' from cte For XML PATH ('')
You need to pivot your data if you have situations where there are two rows, and you want two columns. Your sql is a bit messy, particularly the bit where you put an entire select statement inside a case when in the select part of another query. These two queries are virtually the same, you should look for a more optimal way of writing them. However, you can wrap your entire sql in the following:
select
Jobcode, shipmentsyskey, [M],[I]
from(
--YOUR ENTIRE SQL GOES HERE BETWEEN THESE BRACKETS. Do not alter anything else, just paste your entire sql here
) yoursql
pivot(
max(invoiceno)
for docType in([M],[I])
)pvt

Add CDept_Id In first query for result

In my first query, I want to get CDept_Id. But CDept_Id column does not exist in inward_doc_tracking_hdr table.
It comes from inward_doc_tracking_trl table. like below
SELECT CDept_id
FROM inward_doc_tracking_trl
WHERE ref_mkey IN ( SELECT mkey
FROM inward_doc_tracking_hdr
WHERE doc_no = 'IW/HU/16/42' )
So, From this. I get CDept_Id. Now I want to add this in my below query.
SELECT mkey ,
Delivered_By ,
Department_Id ,
( SELECT mkey
FROM erp190516.dbo.emp_mst
WHERE mkey IN ( SELECT employee_mkey
FROM erp190516.dbo.user_mst
WHERE mkey = To_User )
) User_Id ,
Doc_Type ,
Email_Id ,
Ref_No ,
CONVERT(VARCHAR(25), Ref_date, 103) Ref_date ,
Inward_Amt ,
Remarks ,
party_name ,
disp_through
FROM erp190516.dbo.inward_doc_tracking_hdr ,
CDept_id -- add CDept_id here
WHERE doc_no = 'IW/HU/16/42'
AND Status_Flag = '13'
How to add this
UPDATE
inward_doc_tracking_hdr mkey is equal to inward_doc_tracking_trl ref_mkey
It is reading the magic glass bulb, but I think you might nead an INNER JOIN to the other table using the mkey and ref_mkey as link:
Select hdr.mkey
,hdr.Delivered_By
,hdr.Department_Id
,hdr.Doc_Type,Email_Id
,hdr.Ref_No
,convert(varchar(25),hdr.Ref_date,103) Ref_date
,hdr.Inward_Amt
,hdr.Remarks
,hdr.party_name
,hdr.disp_through
,trl.CDept_Id
from erp190516.dbo.inward_doc_tracking_hdr AS hdr
inner join erp190516.dbo.inward_doc_tracking_trl AS trl on hdr.mkey=trl.ref_mkey
where hdr.doc_no = 'IW/HU/16/42'
and hdr.Status_Flag = '13'
UPDATE ...even more guessing...
--First CTE to get the partioned order of CDept_Id
;WITH OrderedCDept AS
(
SELECT ROW_NUMBER() OVER(PARTITION BY ref_mkey ORDER BY CDept_Id DESC) AS SortInx
,ref_mkey
,CDept_Id
FROM erp190516.dbo.inward_doc_tracking_trl
)
--Second CTE to use TOP 1 WITH TIES to fetch all first rows
,LatestCDept AS
(
SELECT TOP 1 WITH TIES *
FROM OrderedCDept
ORDER BY SortInx
)
--Now use the second CTE instead of the table to join
Select hdr.mkey
,hdr.Delivered_By
,hdr.Department_Id
,hdr.Doc_Type,Email_Id
,hdr.Ref_No
,convert(varchar(25),hdr.Ref_date,103) Ref_date
,hdr.Inward_Amt
,hdr.Remarks
,hdr.party_name
,hdr.disp_through
,trl.CDept_Id
from erp190516.dbo.inward_doc_tracking_hdr AS hdr
inner join LatestCDept AS trl on hdr.mkey=trl.ref_mkey
where hdr.doc_no = 'IW/HU/16/42'
and hdr.Status_Flag = '13'

Subquery within SubQuery in SQL - DB2

I am having issue when trying to make a the sub query shown in the first filter dynamically based on one of the results returned from the query. Can someone please tell me what I am doing wrong. In the first subquery it worked.
( SELECT
MAX( MAX_DATE - MIN_DATE ) AS NUM_CONS_DAYS
FROM
(
SELECT
MIN(TMP.D_DAT_INDEX_DATE) AS MIN_DATE,
MAX(TMP.D_DAT_INDEX_DATE) AS MAX_DATE,
SUM(INDEX_COUNT) AS SUM_INDEX
FROM
(
SELECT
D_DAT_INDEX_DATE,
INDEX_COUNT,
D_DAT_INDEX_DATE - (DENSE_RANK() OVER(ORDER BY D_DAT_INDEX_DATE)) DAYS AS G
FROM
DWH.MQT_SUMMARY_WATER_READINGS
WHERE
N_COD_METER_CNTX_KEY = 79094
) AS TMP
GROUP BY
TMP.G
ORDER BY
1
) ) AS MAX_NUM_CONS_DAYS
Above is the subquery I am trying to replace 123456 with CTXTKEY or CTXT.N_COD_METER_CNTX_KEY from query. Below is the full code. Please note than in the subquery before "MAX_NUM_CONS_DAYS" it worked. However, it was only one subquery down.
SELECT
N_COD_WM_DWH_KEY,
V_COD_WM_SN_2,
N_COD_SP_ID,
CTXKEY,
V_COD_MIU_SN,
N_COD_POD,
MIU_CAT,
V_COD_SITR_ASSOCIATED,
WO_INST_DATE,
WO_MIU_CAT,
DAYSRECEIVED3,
MAX_NUM_CONS_DAYS,
( CASE WHEN ( DAYSRECEIVED3 = 3 ) THEN 'Y' ELSE 'N' END ) AS GREEN,
( CASE WHEN ( DAYSRECEIVED3 < 3 AND DAYSRECEIVED3 > 0 ) THEN 'Y' ELSE 'N' END ) AS BLUE,
( CASE WHEN ( DAYSRECEIVED3 = 0 AND MAX_NUM_CONS_DAYS >= 5 ) THEN 'Y' ELSE 'N' END ) AS ORANGE,
( CASE WHEN ( DAYSRECEIVED3 = 0 AND MAX_NUM_CONS_DAYS BETWEEN 1 and 4 ) THEN 'Y' ELSE 'N' END ) AS RED
FROM
(
SELECT
WMETER.N_COD_WM_DWH_KEY,
WMETER.V_COD_WM_SN_2,
WMETER.N_COD_SP_ID,
CTXT.N_COD_METER_CNTX_KEY AS CTXKEY,
CTXT.V_COD_MIU_SN,
CTXT.N_COD_POD,
MIU.N_COD_MIU_CATEGORY AS MIU_CAT,
CTXT.V_COD_SITR_ASSOCIATED,
T1.D_DAT_PLAN_INST AS WO_INST_DATE,
T1.N_COD_MIU_CATEGORY AS WO_MIU_CAT,
( SELECT COUNT( DISTINCT D_DAT_INDEX_DATE ) FROM DWH.MQT_SUMMARY_WATER_READINGS WHERE ( N_COD_METER_CNTX_KEY = CTXT.N_COD_METER_CNTX_KEY ) AND D_DAT_INDEX_DATE BETWEEN ( '2013-07-10' ) AND ( '2013-07-12' ) ) AS DAYSRECEIVED3,
( SELECT
MAX( MAX_DATE - MIN_DATE ) AS NUM_CONS_DAYS
FROM
(
SELECT
MIN(TMP.D_DAT_INDEX_DATE) AS MIN_DATE,
MAX(TMP.D_DAT_INDEX_DATE) AS MAX_DATE,
SUM(INDEX_COUNT) AS SUM_INDEX
FROM
(
SELECT
D_DAT_INDEX_DATE,
INDEX_COUNT,
D_DAT_INDEX_DATE - (DENSE_RANK() OVER(ORDER BY D_DAT_INDEX_DATE)) DAYS AS G
FROM
DWH.MQT_SUMMARY_WATER_READINGS
WHERE
N_COD_METER_CNTX_KEY = 79094
) AS TMP
GROUP BY
TMP.G
ORDER BY
1
) ) AS MAX_NUM_CONS_DAYS
FROM DWH.DWH_WATER_METER AS WMETER
LEFT JOIN DWH.DWH_WMETER_CONTEXT AS CTXT
ON WMETER.N_COD_WM_DWH_KEY = CTXT.N_COD_WM_DWH_KEY
LEFT JOIN DWH.DWH_MIU AS MIU
ON CTXT.V_COD_MIU_SN = MIU.V_COD_MIU_SN
LEFT JOIN
( SELECT V_COD_CORR_WAT_METER_SN, D_DAT_PLAN_INST, N_COD_MIU_CATEGORY
FROM DWH.DWH_ORDER_MANAGEMENT_FACT
JOIN DWH.DWH_MIU
ON DWH.DWH_ORDER_MANAGEMENT_FACT.V_COD_MIU_SN = DWH.DWH_MIU.V_COD_MIU_SN
) AS T1
ON WMETER.V_COD_WM_SN_2 = T1.V_COD_CORR_WAT_METER_SN
WHERE
( V_COD_SITR_ASSOCIATED = 'X' )
AND ( ( MIU.N_COD_MIU_CATEGORY <> 4 ) OR ( ( MIU.N_COD_MIU_CATEGORY IS NULL ) AND ( ( T1.N_COD_MIU_CATEGORY <> 4 ) OR ( T1.N_COD_MIU_CATEGORY IS NULL ) ) ) )
)
Error I am getting is:
Error Code: -204, SQL State: 42704
I would say that a good option here would be to use a CTE, or Common Table Expression. You can do something similar to the following:
WITH CTE_X AS(
SELECT VAL_A
,VAL_B
FROM TABLE_A)
,CTE_Y AS(
SELECT VAL_C
,VAL_B
FROM TABLE_B)
SELECT VAL_A
,VAL_B
FROM CTE_X X
JOIN CTE_Y Y
ON X.VAL_A = Y.VAL_C;
While this isn't specific to your example, it does show that CTE's create a sort of temporary "in memory" table that you can access in a subsequent query. This should allow you to issue your inner two subselects as a CTE, and then use the CTE in the "SELECT MAX( MAX_DATE - MIN_DATE ) AS NUM_CONS_DAYS" query.
You cannot reference columns from the outer select in the subselect, no more than 1 level deep anyway. If I correctly understand what you're doing, you'll probably need to join DWH.MQT_SUMMARY_WATER_READINGS and DWH.DWH_WMETER_CONTEXT in the outer select.