从数据库中过滤唯一记录,同时删除双重非空值

时间:2013-08-13 13:58:08

标签: sql sql-server-2008-r2

这有点难以解释,但这里是我在SQL中尝试做的一个例子。我有一个查询返回以下记录:

ID     Z
---   ---
1      A
1      <null>
2      B
2      E
3      D
4      <null>
4      F
5      <null>

我需要过滤此查询,以便每个唯一记录(基于ID)在输出中只出现一次,如果同一ID有多个记录,则输出应包含Z列值为<的记录非空即可。如果给定ID只有一条记录,并且列Z的值为null,则输出仍应返回该记录。因此,上述查询的输出应如下所示:

ID     Z
---   ---   
1      A
2      B
2      E
3      D
4      F
5      <null> 

您将如何在SQL中执行此操作?

6 个答案:

答案 0 :(得分:2)

您可以使用GROUP BY

SELECT
    ID, MAX(Z) -- Could be MIN(Z)
FROM MyTable
GROUP BY ID

聚合函数忽略NULL,只有当组中的所有值都为NULL时才返回它们。

答案 1 :(得分:1)

如果您需要返回2-B和2-E行:

SELECT * 
FROM YourTable t1
WHERE Z IS NOT NULL
    OR NOT EXISTS 
        (SELECT * FROM YourTable  t2 
         WHERE T2.ID = T1.id AND T2.z IS NOT NULL)

答案 2 :(得分:0)

SELECT  ID
        ,Z 
FROM    YourTable
WHERE   Z IS NOT NULL

答案 3 :(得分:0)

DECLARE @T TABLE ( ID INT, Z CHAR(1) )

INSERT  INTO @T
        ( ID, Z )
VALUES  ( 1, 'A' ),
        ( 1, NULL )
    ,   ( 2, 'B' ) ,
        ( 2, 'E' ),
        ( 3, 'D' ) ,
        ( 4, NULL ),
        ( 4, 'F' ),
        ( 5, NULL )

SELECT *
FROM @T

; WITH c AS  (SELECT ID, r=COUNT(*) FROM @T GROUP BY ID)
SELECT t.ID, Z 
FROM @T t JOIN c ON t.ID = c.ID
WHERE c.r =1
UNION ALL
SELECT t.ID, Z 
FROM @T t JOIN c ON t.ID = c.ID
WHERE c.r >=2
    AND z IS NOT NULL

此示例假定您希望为ID = 2返回两行。

答案 4 :(得分:0)

    with tmp (id, cnt_val) as                      
    (select id,                                              
            sum(case when z is not null then 1 else 0 end) 
     from   t                                                
     group  by id)                                           
    select t.id, t.z                                         
    from t                                                   
    inner join tmp on t.id = tmp.id                          
    where tmp.cnt_val > 0 and t.z is not null                
       or tmp.cnt_val = 0 and t.z is null                    

答案 5 :(得分:0)

WITH CTE
AS (
SELECT id
    ,z
    ,ROW_NUMBER() OVER (
        PARTITION BY id ORDER BY coalesce(z, '') DESC
        ) rn
FROM @T
)
SELECT id
,z
FROM CTE
WHERE rn = 1