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

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

我有一张这样的table。

  1. Name| Id | cost
  2. ----------------
  3. A | 1 | 1000
  4. ----------------
  5. A | 1 | 2000
  6. ----------------
  7. B | 2 | 3000
  8. ----------------
  9. B | 2 | 4000

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

  1. Name| Id | cost
  2. ----------------
  3. A | 1 | 1000
  4. ----------------
  5. | | 2000
  6. ----------------
  7. B | 2 | 3000
  8. ----------------
  9. | | 4000

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

xmjla07d

xmjla07d1#

你可以用 row_number() :

  1. select
  2. case when row_number() over(partition by name, id order by cost) = 1
  3. then name
  4. end name,
  5. case when row_number() over(partition by name, id order by cost) = 1
  6. then id
  7. end id,
  8. cost
  9. from mytable

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

gmol1639

gmol16392#

我们能做什么

  1. with tb(Name, Id , cost) as (
  2. select 'A' , 1 , 1000 union all
  3. select 'A' , 1 , 2000 union all
  4. select 'B' , 2 , 3000 union all
  5. select 'B' , 2 , 4000
  6. )
  7. select
  8. case when Row_Nb = 1 then Name else '' end as Name
  9. , case when Row_Nb = 1 then Id else null end as Id
  10. , cost
  11. from(
  12. select row_number() OVER(partition by Name, id order by cost) AS Row_Nb, tb.*
  13. from tb
  14. )x
cygmwpex

cygmwpex3#

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

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

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

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

相关问题