SQL Server 2008 - 使用ROW_NUMBER

时间:2015-12-07 13:05:25

标签: sql sql-server

我有以下用于查找重复项的SQL

SELECT  *
FROM (SELECT
      id,
      ShipAddress,
      ShipZIPPostal,
      ROW_NUMBER() OVER (PARTITION BY shipaddress, shipzippostal ORDER BY shipaddress) ROWNUM
FROM orders
WHERE CONVERT(date, orderdate) = CONVERT(date, GETDATE())) x
WHERE rownum > 1

我想只看到行在哪里,如果Rownum的值> 1然后我想看到其对应的行rownum = 1。

所以基本上,如果一行有重复,我想看到原始行及其所有副本。

如果一行没有重复项,那么我不想看到它(它将有rownum = 1)

我该怎么办?

欢呼声

3 个答案:

答案 0 :(得分:3)

使用count(*)而不是row_number()

SELECT *
FROM (SELECT id, ShipAddress, ShipZIPPostal,
             COUNT(*) OVER (PARTITION BY shipaddress, shipzippostal) as cnt
      FROM orders
      WHERE CONVERT(date, orderdate) = CONVERT(date, GETDATE())
     ) x
WHERE cnt > 1;

答案 1 :(得分:0)

除了Gordon的回答,如果你想出于某些学术原因想保留row_number()方法,你可以这样做:

SELECT  *
FROM (SELECT
      id,
      ShipAddress,
      ShipZIPPostal,
      ROW_NUMBER() OVER (PARTITION BY shipaddress, shipzippostal ORDER BY shipaddress) ROWNUM
FROM orders
WHERE CONVERT(date, orderdate) = CONVERT(date, GETDATE())) x
WHERE EXISTS(
 SELECT * FROM x x2
 WHERE x.shipaddress=x2.shipaddress
 AND x.shipzippostal=x2.shipzippostal
 AND x2.ROWNUM>1
)

我实际上更喜欢这样的cte结构:

WITH cte AS (
  SELECT
      id,
      ShipAddress,
      ShipZIPPostal,
      ROW_NUMBER() OVER (PARTITION BY shipaddress, shipzippostal ORDER BY shipaddress) ROWNUM
  FROM orders
  WHERE CONVERT(date, orderdate) = CONVERT(date, GETDATE())
) 
SELECT  *
FROM cte
WHERE EXISTS(
 SELECT * FROM cte x2
 WHERE cte.shipaddress=x2.shipaddress
 AND cte.shipzippostal=x2.shipzippostal
 AND x2.ROWNUM>1
)

答案 2 :(得分:0)

您可以添加第二个row_number,但是将顺序更改为ID以使其不同,并比较2 row_numbers

SELECT
    *
FROM
    (SELECT
        id,
        ShipAddress,
        ShipZIPPostal,
        ROW_NUMBER() OVER (PARTITION BY shipaddress,shipzippostal ORDER BY id) ROWNUM1,
        ROW_NUMBER() OVER (PARTITION BY shipaddress,shipzippostal ORDER BY id DESC) ROWNUM2
     FROM
        orders
     WHERE
        CONVERT(DATE,orderdate) = CONVERT(DATE,GETDATE())
    ) x
WHERE
    ROWNUM1 <> ROWNUM2