当ID相同时,检查Ordinal是否大于先前的提交

时间:2016-08-18 11:06:54

标签: sql sql-server

示例查询

USE HES 
SELECT T1.ID, T2.DATE, T1.ORDINAL
FROM TABLE1 AS T1   
LEFT JOIN TABLE2 AS T2  
    ON T1.ID = T2.ID AND T1.PARTYEAR = T2.PARTYEAR  
WHERE
    T1.MONTHYEAR = '201501'              

示例查询的结果

ID  Date    Ordinal

1   01/01/2016  1
1   02/01/2016  2
1   03/01/2016  3
2   04/01/2016  1
2   05/01/2016  2
3   06/01/2016  1
3   07/01/2016  2
3   08/01/2016  3    
4   09/01/2016  1
4   10/01/2016  1

问题

每个用户都有一个唯一的ID,对于每个ID,我如何检查每个数据提交包含的序号是否大于先前提交的序号。

因此,在上面的示例查询结果中,ID 4包含一个问题。

我对SQL很新,我一直在寻找类似的例子,但没有成功。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:0)

就像@Serg所说,你可以使用lag

来实现这一点
select *
   from (
    SELECT T1.ID, T2.DATE, T1.ORDINAL, 
           lag(t1.ordinal) over (partition by t1.id order by t2.date) as prevOrdinal
    FROM TABLE1 AS T1   
    LEFT JOIN TABLE2 AS T2  
        ON T1.ID = T2.ID AND T1.PARTYEAR = T2.PARTYEAR  
    WHERE
        T1.MONTHYEAR = '201501') as t
  where t.prevOrdinal >= t.ordinal;

<强>输出

ID  DATE       ORDINAL  prevOrdinal
4   2016-10-01  1       1

答案 1 :(得分:0)

试试这个:

SELECT * INTO #tmp
FROM (VALUES    
(1, CONVERT(date, '01/01/2016'), 1),
(1, '02/01/2016', 2),
(1, '03/01/2016', 3),
(2, '04/01/2016', 1),
(2, '05/01/2016', 2),
(3, '06/01/2016', 1),
(3, '07/01/2016', 2),
(3, '08/01/2016', 3),   
(4, '09/01/2016', 1),
(4, '10/01/2016', 1)
)T(ID, Date, Ordinal)

WITH Numbered AS
(
    SELECT ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Date) R, *
    FROM #tmp
)
SELECT N2.ID, N2.Date, N1.Ordinal Prev, N2.Ordinal Curr
FROM Numbered N1
JOIN Numbered N2 ON N1.R+1=N2.R AND N1.ID=N2.ID
WHERE N1.Ordinal >= N2.Ordinal

当SQL Server版本&gt; = 2012时,可以简化它,#tmp是您当前的结果。

答案 2 :(得分:0)

LAG与OVER子句一起使用:

WITH cte AS
(
    SELECT T1.ID, T2.DATE, T1.ORDINAL, LAG(T1.ORDINAL) OVER(PARTITION BY T1.ID ORDER BY T1.ORDINAL) AS LagOrdinal
    FROM TABLE1 AS T1   
    LEFT JOIN TABLE2 AS T2  
        ON T1.ID = T2.ID AND T1.PARTYEAR = T2.PARTYEAR  
    WHERE
        T1.MONTHYEAR = '201501'
)
SELECT ID, DATE, ORDINAL, CASE WHEN ORDINAL > LagOrdinal THEN 1 ELSE 0 END AS OrdinalIsGreater
    FROM cte;