如何在SQL中根据天数和顺序设置标志

时间:2018-08-08 16:39:00

标签: sql-server sql-server-2008 sql-scripts

样本表(事件)具有以下数据,

+-----+-------------+------+----------+
| Ref |  In_Date    | Item | Customer |
+-----+-------------+------+----------+
|   1 | 5-Apr-2018  | DELL | ABC      |
|   2 | 11-Apr-2018 | DELL | ABC      |
|   3 | 13-Apr-2018 | DELL | ABC      |
|   4 | 19-Apr-2018 | DELL | ABC      |
|   5 | 25-Apr-2018 | DELL | ABC      |
|   6 | 27-Apr-2018 | DELL | ABC      |
|   7 | 29-Apr-2018 | DELL | ABC      |
|   8 | 10-Apr-2018 | HP   | XYZ      |
|   9 | 12-Apr-2018 | HP   | XYZ      |
|  10 | 30-Apr-2018 | IBM  | JKL      |
+-----+-------------+------+----------+

按照下面的查询,将得到类似事件(按项目和客户)计数> 1。

SELECT * FROM
(
    SELECT Ref, In_Date, Item, Customer,
    COUNT(*) OVER (PARTITION BY Customer, Item) AS cnt
    FROM Incident
) t
WHERE cnt > 1
ORDER BY Item, Customer;

我要为每个结果行设置一个具有以下条件的标志,

  • 在相似的事件组中,如果日期差与最近的日期相差3天以上,则标记为“ 0”(例如:参考1和4结果表)
  • 如果类似事件组中的最近日期为最近3天,则标记为“ 2”(例如参考编号:3,7和9)
  • 将“ 1”标记为与最新日期相差3天(例如:ref:2、5、6和8)

预期结果:

+-----+-------------+------+----------+------+
| Ref |   In_Date    | Item | Customer | Flag |
+-----+-------------+------+----------+------+
|   1 | 5-Apr-2018  | DELL | ABC      |    0 |
|   2 | 11-Apr-2018 | DELL | ABC      |    1 |
|   3 | 13-Apr-2018 | DELL | ABC      |    2 |
|   4 | 19-Apr-2018 | DELL | ABC      |    0 |
|   5 | 25-Apr-2018 | DELL | ABC      |    1 |
|   6 | 27-Apr-2018 | DELL | ABC      |    1 |
|   7 | 29-Apr-2018 | DELL | ABC      |    2 |
|   8 | 10-Apr-2018 | HP   | XYZ      |    1 |
|   9 | 12-Apr-2018 | HP   | XYZ      |    2 |
+-----+-------------+------+----------+------+

2 个答案:

答案 0 :(得分:0)

如肖恩(Sean)在评论中所说,使用联接将表自身联接起来

类似这样的东西:

SELECT
        THISRECORD.Ref,
        THISRECORD.In_Date,
        THISRECORD.Item,
        THISRECORD.Customer,
        CASE WHEN (datediff(day,lASTRECORD.In_Date,THISRECORD.In_Date) > 3)  THEN 0
        WHEN (datediff(day,lASTRECORD.In_Date,THISRECORD.In_Date) = 3)  THEN 1
        ELSE 2 END AS Flag

FROM 
    MYTABLE AS THISRECORD
LEFT JOIN MYTABLE AS lASTRECORD
ON THISRECORD.REF-1 = lASTRECORD.REF

答案 1 :(得分:0)

该查询如何:

;with cte as 
(SELECT Ref,E_date,
Item,Customer
FROM
       (SELECT Ref, E_Date, Item, Customer,
       COUNT(*) OVER (PARTITION BY Customer, Item) AS cnt
       FROM incident
       ) t
WHERE cnt > 1
)

select a.Ref,a.E_Date,a.Item, a.Customer,
case when ((abs(DATEDIFF(dd,b.E_Date,a.E_Date))>3 or DATEDIFF(dd,b.E_Date,a.E_Date) is null ) and abs(DATEDIFF(dd,a.E_Date,c.E_Date))<=3)
          or (abs(DATEDIFF(dd,b.E_Date,a.E_Date))<=3 and abs(DATEDIFF(dd,a.E_Date,c.E_Date))<=3) then 1
when (abs(DATEDIFF(dd,b.E_Date,a.E_Date))<=3 and (abs(DATEDIFF(dd,a.E_Date,c.E_Date))>3 or abs(DATEDIFF(dd,a.E_Date,c.E_Date)) is null  )) then 2
else 0 end as Flag
from cte a  
left join cte b on a.Ref=b.Ref+1 
left join cte c on a.Ref=c.Ref-1
group by a.Item,a.Customer,a.REf,a.E_Date,b.E_Date,c.E_Date