尝试编写将显示重复项的查询结果为null

时间:2017-03-23 17:41:10

标签: sql sql-server tsql

我有一张看起来像第一个例子的表 我正在尝试编写一个MSSQL2012语句,它将显示第二个示例的结果。

基本上我想在第1列和第2列中使用空值而不是重复值。这是为了在报告期间的可读性。

这似乎应该是可能的,但我正在画一个空白。我写的任何数量的连接或联合都没有提供我需要的结果。

| Col1 | Col2 | Col3 |
+------+------+------+
| 1    | 2    |    4 |
| 1    | 2    |    5 |
| 1    | 3    |    6 |
| 1    | 3    |    7 |
+------+------+------+


| Col1 | Col2 | Col3 |
+------+------+------+
| 1    | 2    |    4 |
| Null | null |    5 |
| null | 3    |    6 |
| null | null |    7 |
+------+------+------+

2 个答案:

答案 0 :(得分:3)

我会这样做,根本没有子查询:

select (case when row_number() over (partition by col1 order by col2, col3) = 1
             then col1
        end) as col1,
       (case when row_number() over (partition by col2 order by col3) = 1
             then col2
        end) as col2,
       col3
from t
order by t.col1, t.col2, t.col3;

请注意,查询末尾的order by非常重要。您想要的结果集主要取决于行的顺序。如果没有order by,结果集可以按任何顺序排列。因此,查询可能看起来有效,然后突然失败一天或稍微不同的数据集。

答案 1 :(得分:2)

使用common table expression row_number()

;with cte as (
select *
  , rn_1 = row_number() over (partition by col1 order by col2, col3)
  , rn_2 = row_number() over (partition by col1, col2 order by col3)
from t
)
select 
    col1 = case when rn_1 > 1 then null else col1 end
  , col2 = case when rn_2 > 1 then null else col2 end
  , col3
from cte 

没有cte

select 
    col1 = case when rn_1 > 1 then null else col1 end
  , col2 = case when rn_2 > 1 then null else col2 end
  , col3
from (
  select *
    , rn_1 = row_number() over (partition by col1 order by col2, col3)
    , rn_2 = row_number() over (partition by col1, col2 order by col3)
  from t
  ) sub

rextester 演示http://rextester.com/UYA17142

返回:

+------+------+------+
| col1 | col2 | col3 |
+------+------+------+
| 1    | 2    |    4 |
| NULL | NULL |    5 |
| NULL | 3    |    6 |
| NULL | NULL |    7 |
+------+------+------+