SQL unionall,null

时间:2015-11-16 16:16:58

标签: sql oracle

所以我有第一个表,需要将其转换为第二个表。也就是说,制造商应该只出现在第一行,并在以后的事件中替换为NULL。

MAKER   TYPE        RNK
A       PC          1
A       Laptop      2
A       Printer     3
B       PC          1
B       Laptop      2
C       Laptop      1
D       Printer     1
E       PC          1
E       Printer     2


MAKER   TYPE      RNK
A       PC         1  
NULL    Laptop     2 
NULL    Printer    3
B       PC         1
NULL    Laptop     2 
C       Laptop     1
D       Printer    1
E       PC         1
NULL    Printer    2

我试过

select maker, type, rnk from a1 where rnk = 1
union all
select '', type, rnk from a1 where rnk = 2 
union all
select '', type, rnk  from a1 where rnk = 3

但这并没有保留顺序,因为默认情况下所有的空值都会像这样

组合在一起
A       PC         1        
B       PC         1     
C       Laptop     1     
D       Printer    1      
E       PC         1      
NULL    Laptop     2      
NULL    Printer    3      
NULL    Laptop     2       
NULL    Printer    2  

2 个答案:

答案 0 :(得分:2)

我同意在sql之外做这种事情,但只需使用CASE表达式和ORDER BY来完成:

SELECT CASE WHEN rnk = 1 THEN MAKER ELSE '' END AS Mkr, type, rnk 
FROM Table1
ORDER BY MAKER,RNK

演示:SQL Fiddle

答案 1 :(得分:0)

这种操作应该在表示层完成!

在我看来,你想要在raport中合并单元格。 DB不适合进行此类操作。

enter image description here enter image description here

但如果你坚持你可以使用......:/ / p>

WITH cte AS (
 SELECT *, i = DENSE_RANK() OVER(ORDER BY Maker)
  FROM tab
)
select maker, type, rnk,i from cte a1 where rnk = 1
union all
select '', type, rnk,i from  cte a1 where rnk = 2 
union all
select '', type, rnk,i  from cte a1 where rnk = 3
ORDER BY i, rnk;

LiveDemo

或使用简单的CASE

WITH cte AS(
  select maker, type, rnk from tab a1 where rnk = 1
  union all
  select maker, type, rnk from tab a1 where rnk = 2 
  union all
  select maker, type, rnk from tab a1 where rnk = 3
)
SELECT CASE WHEN rnk <> 1 THEN '' ELSE maker END AS maker_name,
     type,
     rnk
FROM cte
ORDER BY maker, rnk;

LiveDemo2