如何为每个组的列选择非空值?

时间:2019-05-09 17:54:48

标签: sql group-by

我有下表。

| col1 | col2 | col3 | col4 |
| ---- | ---- | ---- | ---- |
| 123  | 345  | LA   | 001  |
| 123  | 345  | AB   |      |
| 123  | 345  | LA   |      |
| 123  | 345  |      |      |
| abc  | cde  | LA   |      |
| abc  | cde  |      |      |
| abc  | cde  | AB   |      |
| abc  | cde  | LA   |      |
| ooo  | zzz  | LA   |      |
| ooo  | zzz  | LA   | 001  |
| ooo  | zzz  | LA   |      |
| ooo  | zzz  | LA   | 001  |
| 12   | 35   | LA   |      |
| 12   | 35   | LA   |      |
| 12   | 35   | LA   |      |
| 12   | 35   | LA   |      |

我想为col1col2的每个组选择,如果col3必须存在AB,否则它是blank ,如果存在col4值,则non-blank应该是non-blank,否则应该是blank。每个组的col4的值将为unique non-blankblank

所需的输出:

| col1 | col2 | col3 | col4 |
|------|------|------|------|
| 123  | 345  | AB   | 001  |
| abc  | cde  | AB   |      |
| ooo  | zzz  |      | 001  |
| 12   | 35   |      |      |

所需代码:

select col1, col2,
(AB if AB present else blank) as col3,
(non-blank value if non-blank is present else blank) as col4
from test
group by col1, col2;

到目前为止,我已经尝试过:

select col1, col2,
max(col4) as col4
from test
group by col1, col2;

我不知道该如何col3

SQL小提琴:https://www.db-fiddle.com/f/dtEiDdu6Arn6VQTGwMXm4q/0

注意:

  1. 我需要与供应商无关的解决方案。我认为 RDBMS特定解决方案可能可以在我使用的平台上工作,但我必须测试该答案/解决方案并与您联系。

  2. 我不是从源查询,而是从网格查询,因此我不在后端使用RDBMS。

4 个答案:

答案 0 :(得分:2)

对于列col3,您需要一个CASE语句;对于列col4,只需MAX()(或MIN()):

select 
  col1, 
  col2,
  case when sum(case when col3 = 'AB' then 1 else 0 end) > 0 then 'AB' else null end col3,
  max(col4) col4
from test 
group by col1, col2;

请参见demo
结果:

| col1 | col2 | col3 | col4 |
| ---- | ---- | ---- | ---- |
| 12   | 35   |      |      |
| 123  | 345  | AB   | 001  |
| abc  | cde  | AB   |      |
| ooo  | zzz  |      | 001  |

答案 1 :(得分:0)

这是一个优先级查询。经常使用row_number()

select col1, col2, (case when col3 = 'AB' then col3 end) as col3,
       col4
from (select t.*,
             row_number() over (partition by col1, col2
                                order by (case when col3 = 'AB' then 1 else 2 end),
                                         (case when col4 <> '' then 1 else 2 end)
                               ) as seqnum
      from t
     ) t
where seqnum = 1;

答案 2 :(得分:0)

检查此-

SELECT B.col1,B.col2,B.N_Col3,MAX(B.col4)
FROM
(   
    SELECT your_table.*,A.col3 N_Col3
    FROM your_table
    LEFT JOIN 
    (   
        SELECT * FROM your_table
        WHERE col3 = 'AB'
    )A
    ON A.col1 = CTE.col1 AND A.col2 = CTE.col2
)B
GROUP BY B.col1,B.col2,B.N_Col3
ORDER BY 3 DESC

答案 3 :(得分:0)

select col1, col2, max(col3) col3, max(col4) col4
from
(
    select col1, col2, case when col3 = 'AB' THEN 'AB' ELSE '  ' END col3, max(COL4) col4
    from @table
    group by col1, col2, case when col3 = 'AB' THEN 'AB' ELSE '  ' END
) A
group by col1, col2