【问题标题】:Select value from different row based on value of certain column根据某列的值从不同行中选择值
【发布时间】:2020-02-20 20:27:16
【问题描述】:

例如我有这样的数据

    date     |  col_1 |   Col_2 |   Col_3   | Col_4
---------------------------------------------
 20021   |   1    |   a     |   null    |   a
 20022   |   2    |   a     |   null    |   a
 20023   |   3    |   a     |   null    |   a
 20024   |   4    |   a     |   4.5     |   a
 20031   |   1    |   a     |   11      |   b
 20032   |   2    |   a     |   2       |   b
 20033   |   3    |   a     |   9       |   b
 20034   |   4    |   a     |   11      |   b

我需要的是当 Col_3 中的值为 null 而 Col_1 不是 4 时, 然后选择 Col_3 中的值,其中 Col_1 = 4,具有相同的

我尝试使用这个案例陈述:

select col_2, date, col_1, col_4,
   case when col_3 is null and col_1 != 1
     then (select col_3 from table s where s.date = 4
           and s.col_1= seg.col_1 and s.col_4= seg.col_4
           and left(s.date,4) = left(seg.date,4))
    else seg.col_3
  end as col_3
from table seg

但由于某种原因,它没有做我需要做的事情 我需要它把上表的结果改成这样:

    date     |  col_1 |   Col_2 |   Col_3   | Col_4
---------------------------------------------
 20021   |   1    |   a     |   4.5    |   a
 20022   |   2    |   a     |   4.5    |   a
 20023   |   3    |   a     |   4.5    |   a
 20024   |   4    |   a     |   4.5     |   a
 20031   |   1    |   a     |   11      |   b
 20032   |   2    |   a     |   2       |   b
 20033   |   3    |   a     |   9       |   b
 20034   |   4    |   a     |   11      |   b

【问题讨论】:

  • 编辑问题也添加预期结果。
  • 那个子查询似乎有点冒险。它可能会返回超过 1 行,这意味着引发了错误。
  • 能否提供一个输出示例,这样会增加得到回复的机会。
  • 感谢您的建议,我编辑并添加了预期结果
  • @Shadizz 您想从 Col1=4 的记录中更新值 Col3 .. 一切正常。但是对于 Date = 20024 & 20034 有 2 条 Col1=4 的记录,但您更新的值仅为 4.5,而另一条记录的值为 11。应再次细化要求。

标签: sql sql-server


【解决方案1】:

也许使用OUTER APPLY(或CROSS APPLY,如果您可以保证第 4 季度在那里)总是有每个 col4 每年可用的第 4 季度,然后在需要的地方使用它。

select col_2, date, col_1, col_4,
   case when col_3 is null and col_1 != 4
     then backfill.col_3
    else seg.col_3
  end as col_3
from table seg
outer apply (select col_3 from table where col_1 = 4 and left(date,4) = left(seg.date,4)) and col_4 = seg.col_4) backfill

如果您宁愿坚持使用 CASE,这应该可以。

case when col_3 is null and col_1 != 4
     then (select col_3 from table s where s.col_1 = 4 
           and s.col_4 = seg.col_4
           and left(s.date,4) = left(seg.date,4))
    else seg.col_3

【讨论】:

    【解决方案2】:

    只需使用窗口函数和coalesce():

    select date, col1, col2, 
           coalesce(max(case when col1 = 4 then col3 end) over (partition by col4) as col3,
           col4
    from t;
    

    【讨论】:

      猜你喜欢
      • 2020-09-29
      • 1970-01-01
      • 2017-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多