选择另一个字段,其他第一个非空或空

时间:2017-09-18 10:03:27

标签: sql sql-server distinct

我有桌子

| Id  | val  |
| --- | ---- |
| 1   | null |
| 1   | qwe1 |
| 1   | qwe2 |
| 2   | null |
| 2   | qwe4 |
| 3   | qwe5 |
| 4   | qew6 |
| 4   | qwe7 |
| 5   | null |
| 5   | null |

是否有任何简单的方法可以使用第一个非null'val'值来选择不同的'id'值。如果不存在则为null。例如 结果应该是

| Id  | val  |
| --- | ---- |
| 1   | qwe1 |
| 2   | qwe4 |
| 3   | qwe5 |
| 4   | qew6 |
| 5   | null |

3 个答案:

答案 0 :(得分:2)

在您的情况下,一个简单的GROUP BY应该是解决方案:

  SELECT Id
        ,MIN(val) 
    FROM dbo.mytable
GROUP BY Id

每当使用GROUP BY时,您必须对GROUP BY中未列出的所有列使用聚合函数。

如果Id的值(val)不是NULL,则返回此值。
如果该ID只有NULLs,则会返回NULL 据我所知(关于你的评论),这正是你要接近的。

如果您始终希望“第一个”值<> NULL,您需要另一个排序条件(如时间戳列),并且可以使用WINDOW-function解决此问题。

答案 1 :(得分:1)

如果您想要第一个NULL值(其中"第一个"基于id),那么MIN()不会#39;做得很好。窗函数可以:

select t.*
from (select t.*,
             row_number() over (partition by id
                                 order by (case when val is not null then 1 else 2 end),
                                          id
                               ) as seqnum
      from t
     ) t
where seqnum = 1;

答案 2 :(得分:1)

SQL Fiddle:

Create Table from SQL Fiddle:

CREATE TABLE tab1(pid integer,id integer,val varchar(25))

Insert dummy records :
 insert into tab1 
    values (1, 1   , null),
    (2, 1   , 'qwe1' ),
    (3, 1   , 'qwe2'),
    (4, 2   , null ),
    (5, 2   , 'qwe4' ),
    (6, 3   , 'qwe5' ),
    (7, 4   , 'qew6' ),
    (8, 4   , 'qwe7' ),
    (9, 5   , null ),
    (10, 5   , null );
fire below query:
SELECT Id  ,MIN(val) as val  FROM tab1  GROUP BY Id;