2

This is kind of hard to explain in words but here is an example of what I am trying to do in SQL. I have a query which returns the following records:

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

I need to filter this query so that each unique record (based on ID) appears only once in the output and if there are multiple records for the same ID, the output should contain the record with the value of Z column being non-null. If there is only a single record for a given ID and it has value of null for column Z the output still should return that record. So the output from the above query should look like this:

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

How would you do this in SQL?

4

6 回答 6

2

您可以GROUP BY为此使用:

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

聚合函数忽略NULLs,仅当组中的所有值都是 时才返回它们NULL

于 2013-08-13T14:08:23.373 回答
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)
于 2013-08-13T14:17:09.427 回答
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                    
于 2013-08-13T14:39:26.850 回答
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
于 2013-08-13T19:54:39.570 回答
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 返回两行。

于 2013-08-13T14:20:58.797 回答
0
SELECT  ID
        ,Z 
FROM    YourTable
WHERE   Z IS NOT NULL
于 2013-08-13T14:07:32.120 回答