sql server—如何使sql select查询在该行的CLO与上一行的值重复时,使后续行中的某些列留空?

d6kp6zgx  于 2021-07-26  发布在  Java
关注(0)|答案(3)|浏览(353)

我有一张这样的table。

Name|  Id |  cost
  ----------------
  A  |  1  |  1000
  ----------------
  A  |  1  |  2000
  ----------------
  B  |  2  |  3000
  ----------------
  B  |  2  |  4000

注意:数据已按排序顺序排列
我需要的结果是:

Name|  Id |  cost
  ----------------
  A  |  1  |  1000
  ----------------
     |     |  2000
  ----------------
  B  |  2  |  3000
  ----------------
     |     |  4000

因为“a”已经存在于我们的查询中,所以下一行的“name”中应该有一个空值,并且与“a”关联的id是1,这也是重复的,因此它也应该是空的。b的情况也类似。
如何在单个select查询中实现这一点?

xmjla07d

xmjla07d1#

你可以用 row_number() :

select
    case when row_number() over(partition by name, id order by cost) = 1
        then name
    end name,
    case when row_number() over(partition by name, id order by cost) = 1
        then id
    end id,
    cost
from mytable

这假设你想要 (name, id) 元组排序依据 cost (如示例数据所示)。如果要使用另一个排序列,则可以更改 order by 窗口函数的子句。

gmol1639

gmol16392#

我们能做什么

with tb(Name,  Id ,  cost) as (
 select 'A'  ,  1  ,  1000 union all
  select 'A'  ,  1  ,  2000 union all
  select 'B'  ,  2  ,  3000 union all
  select 'B'  ,  2  ,  4000
  )

  select
    case when Row_Nb = 1 then Name else '' end as Name
    ,  case when Row_Nb = 1 then Id else null end as Id 
    ,  cost
  from(
    select row_number() OVER(partition by  Name, id order by cost) AS Row_Nb, tb.*
    from tb
  )x
cygmwpex

cygmwpex3#

我不建议将此作为数据库查询。结果集将包含没有意义的行,除非您看到它们上面的行——这不是sql方式。
我建议首先进行汇总,并将成本放在一行中:

select name, id, string_agg(cost, ', ') as costs
from t
group by name, id;

如果你真的坚持这个结果集,有一个 order by 在外部查询中——因为没有 order by 结果可以是任何顺序。因此,我认为最好的解决办法是:

select (case when seqnum = 1 then name end) as name,
       (case when seqnum = 1 then id end) as id,
       cost
from (select t.*, row_number() over (partition by name, id order by cost) as seqnum
      from t
     ) t
order by name, id, seqnum

相关问题