2015-03-02 53 views
1

我有一個如下所示的長表。該表在id更改後添加兩個相似的行。例如,當ID從1變爲2時,添加重複記錄。我只需要一個SELECT查詢來跳過這個以及所有其他重複記錄,只有當這個ID改變了。SQL Server中ID更改後跳過第一行的查詢

# | name| id 
--+-----+--- 
1 | abc | 1 
2 | abc | 1 
3 | abc | 1 
4 | abc | 1 
5 | abc | 1 
5 | abc | 2 
6 | abc | 2 
7 | abc | 2 
8 | abc | 2 
9 | abc | 2 

+9

請編輯您的問題與你想要的輸出。而且,行是否有唯一的ID? – 2015-03-02 12:55:55

+0

@thanks marc_s,是行有唯一的id。 – 2015-03-02 12:58:55

回答

0

所以我通過在SQL Server中使用以下查詢來實現它。

select #, name, id 
from table 
group by #, name, id 
having count(*) > 0 
0

您可以使用以下CTEs模擬在SQL Server 2008中不可用LAG窗口功能:

;WITH CTE_RN AS (
    SELECT *, ROW_NUMBER() OVER (ORDER BY [#], id) AS rn 
    FROM #mytable 
), CTE_LAG AS (
    SELECT t1.[#], t1.name, 
      t1.id AS curId, t2.id AS prevId, 
      t1.[#] AS cur#, t2.[#] AS lag# 
    FROM CTE_RN t1 
    LEFT JOIN CTE_RN t2 ON t1.rn = t2.rn + 1) 

現在可以使用過濾掉「重複」記錄以上CTE_LAG和以下謂詞在您的WHERE子句中:

;WITH ( 
    ... cte definitions here 
) SELECT * 
FROM CTE_LAG 
WHERE (NOT ((prevId <> curId) AND (cur# = lag#))) OR (prevId IS NULL) 

如果prevId <> curIdcur# = lag#,則有在id以下記錄的值的變化具有相同的值[#]與前一個,即它是一個重複。

因此,在(prevId <> curId) AND (cur# = lag#)上使用NOT,過濾掉所有'重複'記錄。這意味着記錄(5, abc, 2)將被淘汰。

SQL Fiddle Demo here

附:您還可以在WHERE子句的邏輯表達式中添加第name列,具體取決於定義「重複」的內容。

0

你可以使用NOT EXISTS來消除重複:

SELECT * 
FROM yourtable AS T 
WHERE NOT EXISTS 
     ( SELECT 1 
      FROM yourtable AS T2 
      WHERE T.[#] = T2.[#] 
      AND  T2.ID > T.ID 
     ); 

這將返回:

# name ID 
------------------ 
. ...  . 
4 abc  1 
5 abc  2 
6 abc  2 
. ...  . 

...(一些無關痛癢的行已經從一開始和結束時刪除)

如果您想要保留第一條記錄而不是最後一條,那麼只需更改條件T2.ID > T.IDT2.ID < T.ID