【发布时间】:2019-03-19 17:47:29
【问题描述】:
我有以下 SQL 来获取最高(最大)和第二高日期行。数据中有一些情况,“旧行”和“新行”的唯一区别是生效日期。我想做的只是显示每个 EMPLID 的旧行和新行,其中 BANK_CD 和/或 ACCOUNT_NUM 在“旧”行和“新”行之间是不同的。
WITH CTE AS (
SELECT A.EMPLID
, C.VENDOR_ID
, B.FIRST_NAME
, B.LAST_NAME
, A.BANK_CD
, A.ACCOUNT_NUM
, A.ACCOUNT_TYPE
, A.PRIORITY
, A.LAST_UPDATE_DATE
, A.EFFDT
, MAX(A.LAST_UPDATE_DATE) OVER(PARTITION BY A.EMPLID) AS MAX_UPDATE_DATE
, ROW_NUMBER() OVER(PARTITION BY A.EMPLID
ORDER BY A.EFFDT DESC
, D.EFFDT DESC) AS RN
FROM PS_DIRECT_DEPOSIT D INNER JOIN PS_DIR_DEP_DISTRIB A ON A.EMPLID = D.EMPLID
AND A.EFFDT = D.EFFDT INNER JOIN PS_EMPLOYEES B ON B.EMPLID = A.EMPLID INNER JOIN PS_GHS_DIR_DEP_VND C ON C.EMPLID = A.EMPLID
INNER JOIN PS_DIR_DEP_DISTRIB E ON E.EMPLID = A.EMPLID AND E.EFFDT = A.EFFDT AND E.PRIORITY = A.PRIORITY
WHERE B.EMPL_STATUS NOT IN ('T','R','D')
AND ((A.DEPOSIT_TYPE = 'P'
AND A.AMOUNT_PCT = 100)
OR A.PRIORITY = 999
OR A.DEPOSIT_TYPE = 'B')
AND D.EFF_STATUS = 'A' )
SELECT CASE WHEN RN = 1 THEN 'NEW ROW' WHEN RN = 2 THEN 'OLD ROW' END AS
'ROW_TYPE' , *
FROM CTE
WHERE RN IN (1, 2)
AND MAX_UPDATE_DATE >= GETDATE() - 8
这是我现在得到的输出示例:
ROW_TYPE EMPLID VENDOR_ID FIRST_NAME LAST_NAME BANK_CD ACCOUNT_NUM ACCOUNT_TYPE PRIORITY LAST_UPDATE_DATE EFFDT MAX_UPDATE_DATE RN
NEW ROW 12345 XYZ123 John Smith 111111122 45678 C 999 03/12/2019 03/12/2019 03/12/2019 1
OLD ROW 12345 XYZ123 John Smith 111111122 45678 C 999 10/25/2017 10/25/2017 10/25/2017 2
NEW ROW 47831 A86464 Samm Bulle 754566654 98865 C 999 03/12/2019 06/08/2018 03/12/2019 1
OLD ROW 47831 A86464 Samm Bulle 754566654 45678 C 999 10/25/2017 06/08/2018 10/25/2017 2
NEW ROW 32456 KG4561 Kilo Renne 875123311 32146 C 300 09/02/2018 09/02/2018 09/02/2018 1
OLD ROW 32456 KG4561 Kilo Renne 971215477 78131 C 310 12/21/2017 12/21/2017 12/21/2017 2
在上面的示例中,我不想输出前两组 EMPLID 行(前 4 行),因为它们在新旧行之间具有相同的 BANK_CD 和 ACCOUNT_NUM。我想保留在输出中的最后一组行,因为您可以看到 BANK_CD 和 ACCOUNT_NUM 是不同的(可能包含其中之一)。
我尝试为 PS_DIR_DEP_DISTRIB 添加自联接,然后添加 WHERE 子句 where AND (A.BANK_CD E.BANK_CD OR A.ACCOUNT_NUM E.ACCOUNT_NUM),如下所示:
WITH CTE AS (
SELECT A.EMPLID
--, C.VENDOR_ID
, B.FIRST_NAME
, B.LAST_NAME
, A.BANK_CD
, A.ACCOUNT_NUM
, A.ACCOUNT_TYPE
, A.PRIORITY
, A.LAST_UPDATE_DATE
, A.EFFDT
, MAX(A.LAST_UPDATE_DATE) OVER(PARTITION BY A.EMPLID) AS MAX_UPDATE_DATE
, ROW_NUMBER() OVER(PARTITION BY A.EMPLID
ORDER BY A.EFFDT DESC
, D.EFFDT DESC) AS RN
FROM PS_DIRECT_DEPOSIT D INNER JOIN PS_DIR_DEP_DISTRIB A ON A.EMPLID = D.EMPLID
AND A.EFFDT = D.EFFDT INNER JOIN PS_EMPLOYEES B ON B.EMPLID = A.EMPLID INNER JOIN PS_GHS_DIR_DEP_VND C ON C.EMPLID = A.EMPLID
---ADDING SELF JOIN BELOW---
INNER JOIN PS_DIR_DEP_DISTRIB E ON E.EMPLID = A.EMPLID AND E.EFFDT =
A.EFFDT AND E.PRIORITY = A.PRIORITY
WHERE B.EMPL_STATUS NOT IN ('T','R','D')
AND ((A.DEPOSIT_TYPE = 'P'
AND A.AMOUNT_PCT = 100)
OR A.PRIORITY = 999
OR A.DEPOSIT_TYPE = 'B')
AND D.EFF_STATUS = 'A'
---ADDING NEW WHERE CONDITION BELOW---
AND (E.ACCOUNT_NUM <> A.ACCOUNT_NUM OR E.BANK_CD <> A.BANK_CD ))
SELECT CASE WHEN RN = 1 THEN 'NEW ROW' WHEN RN = 2 THEN 'OLD ROW' END AS 'ROW_TYPE'
, *
FROM CTE
WHERE RN IN (1, 2)
AND MAX_UPDATE_DATE >= GETDATE() - 8
但是,当我进行上述更改时,我根本没有得到任何数据返回。我做错了什么?
3/20/19 编辑:
按照下面 Tarek 的建议答案,我似乎遗漏了一些我希望在最终输出中出现的行。似乎添加的新字段 BANK_CD_prev 和 ACCOUNT_NUM_prev 在我希望它们显示的行中返回 NULL 值,因此最终查询没有检索它们。该如何处理?
ROW_TYPE EMPLID FIRST_NAME LAST_NAME BANK_CD ACCOUNT_NUM ACCOUNT_TYPE PRIORITY LAST_UPDATE_DATE EFFDT MAX_UPDATE_DATE RN BANK_CD_prev ACCOUNT_NUM_prev
NEW ROW 56789 Test User 874556411 54765 C 999 2019-02-28 2019-02-28 2019-02-28 1 NULL NULL
OLD ROW 56789 Test User 874556411 98451 C 999 2017-10-09 2017-10-09 2017-10-09 1 874556411 54765
NEW ROW 56789 Sampl Test 756561623 46331 C 999 2018-03-12 2018-03-12 2018-03-12 1 NULL NULL
OLD ROW 56789 Test User 756561623 46331 C 999 2015-05-18 2015-05-18 2015-05-18 1 756561623 46331
请注意,上面运行的查询没有(AND BANK_CD <> BANK_CD_prev AND ACCOUNT_NUM <> ACCOUNT_NUM_prev 的最终条件,这样我就可以明白为什么我丢失了一些行。在这种情况下,您可以看到第一个EMPLID的 ACCOUNT_NUM 不同的两行,因此我应该输出两行。第二个EMPLID(最后两行)有点不同,因为BANK_CD 和ACCOUNT_NUM 对于两行都是相同的,所以我不希望这会被输出(它不是,所以这是正确的)但仍然显示NULL's 在第一组行中。
3/20/19 编辑 2:您可以看到 BANK_CD_COUNT 和 ACCOUNT_NUM_COUNT 中有一些我认为会导致问题的奇怪数字。
ROW_TYPE EMPLID FIRST_NAME LAST_NAME BANK_CD ACCOUNT_NUM ACCOUNT_TYPE PRIORITY LAST_UPDATE_DATE EFFDT MAX_UPDATE_DATE RN BANK_CD_COUNT ACCOUNT_NUM_COUNT
NEW ROW 812682 Test User 031308302 8675309 C 999 2019-03-09 2019-03-09 2019-03-09 1 1101 1
OLD ROW 812682 Test User 231379393 0001236408 C 999 2018-04-11 2018-03-03 2019-03-09 2 476 1
此链接包含创建表和插入脚本,供任何可以帮助复制此内容的人使用。
【问题讨论】:
-
嗯...字段 MAX_UPDATE_DATE 的输出应该重复每个 EMPLID 是此 ID 的最大日期。查看演示:rextester.com/QEJB48817
标签: sql sql-server sql-server-2014 gaps-and-islands