查询在SQL Server中更改id后跳过第一行

时间:2015-03-02 12:54:44

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

我有一张如下的长桌子。该表在id更改后添加了两个相似的行。例如,当ID从1变为2时,下表中添加了重复记录。我需要的只是一个SELECT查询,只有在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 

等等

3 个答案:

答案 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_LAGWHERE子句中的以下谓词:

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

如果prevId <> curId cur# = lag#,那么id的值会发生以下变化具有与前一个相同的[#]值,即它是重复的。

因此,在NOT上使用(prevId <> curId) AND (cur# = lag#),过滤掉所有重复的&#39;记录。这意味着记录(5, abc, 2)将被删除。

SQL Fiddle Demo here

P.S。您还可以在name子句的逻辑表达式中添加列WHERE,具体取决于定义&#39;重复&#39;的内容。

答案 1 :(得分: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.ID更改为T2.ID < T.ID

答案 2 :(得分:0)

所以我通过在SQL server中使用以下查询来实现它。

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