SQL查询 - 分区依据

时间:2018-03-09 19:58:08

标签: sql window-functions row-number

从下表中,需要获取绿色的所有记录。对于按sfdc_acc列分区的每个组,根据状态检索最新记录。如果在一个分区中状态为Available或NotAvailable,则需要使用Available检索最新记录。

Table

此查询未按预期返回正确的结果:

SELECT 
    A.* 
FROM
    (SELECT 
         TEMP.*,
         ROW_NUMBER () OVER (PARTITION BY ERP_ACC 
                             ORDER BY LASTMODIFIEDDATE DESC, STATUS ASC) AS RN 
     FROM 
         TEMP) A 
WHERE 
    A.RN = 1

如何修改查询以在分区子句中包含状态检查?

4 个答案:

答案 0 :(得分:0)

为什么不为Available记录应用过滤器。

SELECT A.* FROM
(
    SELECT TEMP.*,ROW_NUMBER () OVER (PARTITION BY ERP_ACC ORDER BY LASTMODIFIEDDATE DESC) AS RN FROM TEMP
    where STATUS = 'Available'
) A WHERE A.RN=1

答案 1 :(得分:0)

我想你想要:

SELECT A.*
FROM (SELECT T.*,
             ROW_NUMBER () OVER (PARTITION BY ERP_ACC, STATUS ORDER BY LASTMODIFIEDDATE DESC) AS RN
      FROM TEMP T
     ) T
WHERE STATUS = 'Available' AND T.RN = 1;

答案 2 :(得分:0)

假设您只需要可用状态:

DECLARE @Table TABLE ( LASTMODIFIEDDATE DATETIME, ERP_ACC int, sfdc_acc VARCHAR(20), status VARCHAR(20))

INSERT INTO @Table VALUES ('3/31/2017', 156, 'ABC', 'Available')
INSERT INTO @Table VALUES ('3/30/2017', 678, 'ABC', 'Available')
INSERT INTO @Table VALUES ('10/17/2016', 872, 'ABC', 'Available')
INSERT INTO @Table VALUES ('08/02/2016', 900, 'ABC', 'Available')
INSERT INTO @Table VALUES ('06/09/2017', 100, 'GHK', 'Not Available')
INSERT INTO @Table VALUES ('05/01/2017', 456, 'GHK', 'Not Available')
INSERT INTO @Table VALUES ('08/02/2016', 954, 'GHK', 'Available')

更新了我的回答,请注意设置排名状态的条件。如果可用则为1,如果不可用,则为2.这将确保状态为“可用”的所有记录都是优先级。

SELECT * FROM 
(SELECT LASTMODIFIEDDATE,
        ERP_ACC,
        sfdc_acc,
        status, ROW_NUMBER () OVER (PARTITION BY sfdc_acc 
        ORDER BY 
        CASE WHEN status = 'Available' THEN 1 ELSE 2 END ASC, 
        LASTMODIFIEDDATE DESC) AS RN FROM @Table) A
WHERE A.RN = 1 

答案 3 :(得分:0)

这样的事情应该有效。您需要先按状态排序,然后按时间戳排序,以便按“可用”排序。先录制,然后再录制其他所有内容。

SELECT 
    A.* 
FROM
    (SELECT 
         TEMP.*,
         ROW_NUMBER () OVER (PARTITION BY ERP_ACC 
                             ORDER BY CASE WHEN STATUS = 'Available' THEN 1 ELSE 2 END, LASTMODIFIEDDATE DESC) AS RN 
     FROM 
         TEMP) A 
WHERE 
    A.RN = 1