Sql server 根据条件筛选重复行

Sql server 根据条件筛选重复行,sql-server,Sql Server,我希望根据条件筛选重复行,以便拾取具有最小修改和最大活动以及唯一rid和did的行。自动加入?或者有更好的方法可以更好地提高性能 例如: id rid modified active did 1 1 2010-09-07 11:37:44.850 1 1 2 1

我希望根据条件筛选重复行,以便拾取具有最小修改和最大活动以及唯一rid和did的行。自动加入?或者有更好的方法可以更好地提高性能

例如:

id        rid                  modified                 active         did
1             1             2010-09-07 11:37:44.850              1             1
2             1             2010-09-07 11:38:44.000              1             1
3             1             2010-09-07 11:39:44.000              1             1
4             1             2010-09-07 11:40:44.000              0             1
5             2             2010-09-07 11:41:44.000              1             1
6             1             2010-09-07 11:42:44.000              1             2
预期产量为

1             1             2010-09-07 11:37:44.850              1             1
5             2             2010-09-07 11:41:44.000              1             1
6             1             2010-09-07 11:42:44.000              1             2
对于第一个答案,当active=0且modified是该行的最小值时,建议不适用于以下数据集

 id        rid                     modified                      active           did
    1             1             2010-09-07 11:37:44.850              1             1
    2             1             2010-09-07 11:38:44.000              1             1
    3             1             2010-09-07 11:39:44.000              1             1
    4             1             2010-09-07 11:36:44.000              0             1
    5             2             2010-09-07 11:41:44.000              1             1
    6             1             2010-09-07 11:42:44.000              1             2

假设SQL Server 2005+。如果希望返回领带,请使用秩而不是行号

;WITH YourTable as
(
SELECT 1 id,1 rid,cast('2010-09-07 11:37:44.850' as datetime) modified, 1 active,1 did union all
SELECT 2,1,'2010-09-07 11:38:44.000', 1,1 union all
SELECT 3,1,'2010-09-07 11:39:44.000', 1,1 union all
SELECT 4,1,'2010-09-07 11:36:44.000', 0,1 union all
SELECT 5,2,'2010-09-07 11:41:44.000', 1,1 union all
SELECT 6,1,'2010-09-07 11:42:44.000', 1,2
),cte as
(
SELECT id,rid,modified,active, did,
ROW_NUMBER() OVER (PARTITION BY rid,did ORDER BY active DESC, modified ASC ) RN
FROM YourTable
)
SELECT id,rid,modified,active, did
FROM cte
WHERE rn=1
order by id

选择id、rid、minmodified、maxactive、按rid从foo组中选择did、按id选择did顺序

如果您有一个表,其中rid和did的每个组合都有一行,则交叉应用可以获得良好的性能:

SELECT
   X.*
FROM
   ParentTable P
   CROSS APPLY (
      SELECT TOP 1 *
      FROM YourTable T
      WHERE P.rid = T.rid AND P.did = T.did
      ORDER BY active DESC, modified
   ) X
用表中的SELECT DISTINCT rid、did替换ParentTable会起作用,但会影响性能

此外,这是我疯狂的单扫描魔法查询,它的性能通常优于其他方法:

SELECT
   id = Substring(Packed, 6, 4),
   rid,
   modified = Convert(datetime, Substring(Packed, 2, 4)),
   Active = Convert(bit, 1 - Substring(Packed, 1, 1)),
   did,
FROM
   (
      SELECT
         rid,
         did,
         Packed = Min(Convert(binary(1), 1 - active) + Convert(binary(4), modified) + Convert(binary(4), id)
      FROM
         YourTable
      GROUP BY
         rid,
         did
   ) X

不推荐使用这种方法,因为它不容易理解,而且很容易出错。但这是一个有趣的奇怪现象,因为在某些情况下,它可以优于其他方法。

如果最小修改和最大活动由两个不同的行持有,会怎么样?两个都应该退回吗?如果不是,是哪一行?输出中是否会有一行active=0?理论上,这可能是最大值,因为没有行具有活动=1。如果活动列对于did只有“0”,则为“是”。否。首先,您在select中包含id,但在group by中不包含id时出错。但是,如果您要将其包括在组中,那么您将返回每一行,因为id是唯一的。谢谢,但我认为它不适用于所述条件-具有最大活动和最小修改的行…请参见下面的示例,老实说,您并不清楚您的意思。这将返回您的预期输出,但有大约3种不同的方式来解释您所说的!2010-09-07 11:37:44.850 112010-09-07 11:38:44.000 1312010-09-07 11:39:44.000 1412010-09-07 11:36:44.000 012010-09-07 11:41:44.000 161010-09-07 11:07 11:42:44.000 12预期输出与前一示例相同112010-09-07 11:37:44.850 11 5 2 2010-09-07 11:41:44.000 1 16 1 2010-09-07 11:42:44.000 1 2操作该编辑在评论编辑器中工作不正常。我已经用第二个示例数据集编辑了原始问题。看起来你只是想使用ORDER BY active DESC,而不是MODIFED ASC?