【问题标题】:SQL Mark Duplicates on same value and similar dateSQL标记重复相同的值和相似的日期
【发布时间】:2014-02-04 08:38:00
【问题描述】:

我有一个如下表 t1。

Reg 字段可能重复,DateSt 最多可能相隔 10 分钟。

我需要根据相同的 Reg 列值选择所有重复记录,但前提是这些值之间的 DateSt 小于 X 秒或分钟等。然后我只需要选择一个...具有最高 Conf 列值并将其余部分标记为重复。

有人可以帮忙吗?非常感谢您的帮助。

ID    CamId     DateSt                  AttributeA     Reg      Conf
--    -----     -------                 ----------     ---      ---
80      5    20/12/2013 12:10:57           E         5897HHS     94
81      5    20/12/2013 12:11:03           E         8526FDB     93
82      5    20/12/2013 12:11:17          GBZ        G6746D      98
83      5    20/12/2013 12:11:40           E         3348DGV     93
84      5    20/12/2013 12:11:49          GBZ        G1229       94
85      5    20/12/2013 12:12:05         NONE        2ACF8       67
86      5    20/12/2013 12:12:05         NONE        992FSW      65
87      5    20/12/2013 12:12:05           E         8852FSW     91
88      5    20/12/2013 12:12:17           E         2132TVA     90
89      5    20/12/2013 12:12:33           E         8832BGV     96
90      5    20/12/2013 12:12:34          UK         SS52BGV     87
91      5    20/12/2013 12:12:35           E         9167DLZ     92
92      5    20/12/2013 12:12:35          UK         S6JLZ       72
93      5    20/12/2013 12:12:42           E         5984OXT     95
94      5    20/12/2013 12:12:43          UK         G12VIV      64

【问题讨论】:

  • sql server版本是sql server 2008及以上吗?
  • 是的。我使用的是 2008 及更高版本。
  • 这些值之间是什么意思?哪些值,重复的?
  • 虽然数据中没有重复的 Reg :) 始终最好为此类问题提供示例来源和预期结果。
  • 注册号可能重复,例如两行注册号为 5897HHS,但日期可能相隔几秒钟

标签: asp.net sql sql-server date


【解决方案1】:

这里是jsfiddle

这是一种开始思考的方法,希望对您有所帮助。

架构和数据设置

CREATE TABLE T
(
  ID     INT,
  CamId  INT,
  DateSt  DATE,
  AttributeA VARCHAR(100),
  Reg  VARCHAR(100),
  Conf INT
  );

INSERT INTO T
VALUES
(90,      5,    GETDATE()-1, 'UK','SS52BGV',8);
INSERT INTO T
VALUES
(90,      5,    GETDATE()-2, 'UK','SS52BGV',44);
INSERT INTO T
VALUES
(90,      5,    GETDATE()-3, 'UK','SS52BGV',3);
INSERT INTO T
VALUES
(90,      5,    GETDATE()-4, 'UK','SS52BGV',5);
INSERT INTO T
VALUES
(90,      5,    GETDATE()-1, 'UK','GHY44',8);
INSERT INTO T
VALUES
(90,      5,    GETDATE()-2, 'UK','GHY44',9);
INSERT INTO T
VALUES
(90,      5,    GETDATE()-3, 'UK','GHY44',66);
INSERT INTO T
VALUES
(90,      5,    GETDATE()-2, 'UK','GHY44',66);
INSERT INTO T
VALUES
(90,      5,    GETDATE()-1, 'UK','KJU13VV',31);
INSERT INTO T
VALUES
(90,      5,    GETDATE()-2, 'UK','KJU13VV',8);

查询

SELECT 
  ID
  ,CAMID
  ,DATEST
  ,ATTRIBUTEA
  ,REG
  ,CONF
  ,CASE WHEN Is_Conf_Max_Dup='Conf_Max' AND ROWN=1 THEN 'Conf_Max' ELSE 'Duplicate' END AS Is_Conf_Max --remove the duplicate Conf values if >=2 rows have the same Max Conf value
FROM
(
  SELECT 
    *
    ,ROW_NUMBER() OVER (PARTITION BY REG ORDER BY CONF DESC, DATEST DESC) AS ROWN
    ,CASE WHEN Conf_Max=Conf THEN 'Conf_Max' ELSE 'Duplicate' END AS Is_Conf_Max_Dup --flag max value of Conf, but duplicate is still possible if 2 rows with same Conf value exists
  FROM
  (
    SELECT
          *
          ,MAX(Conf) OVER (PARTITION BY REG) AS Conf_Max --find max value of Conf
    FROM
    (
      SELECT
        ID
        ,CamId
        ,DateSt
        ,AttributeA
        ,Reg
        ,Conf
        ,MIN(DateSt) OVER (PARTITION BY REG) AS DateSt_Min
        ,MAX(DateSt) OVER (PARTITION BY REG) AS DateSt_Max
      FROM T
    ) A 
    WHERE ABS(DATEDIFF(dd,DateSt_Max,DateSt_Min)) <= 2 --remove rows which are >2 days apart
  ) B
) C

【讨论】:

  • 谢谢...但是当有超过 2 个重复项时它似乎不起作用?有什么想法吗?
猜你喜欢
  • 2012-10-08
  • 2021-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多