我有一个奇怪的场景,我需要在表格中返回最右边的非零列,结构如下:
GL Q1 Q2 Q3 Q4
1 100 0 0 0
2 100 900 250 0
3 600 100 0 1000
我期待输出为:
GL Amount
1 100
2 250
3 1000
无论如何,作为一种基于集合的方法,无需借助CASE声明或类似的解决方案来实现这一目标吗?性能在这里很重要。
答案 0 :(得分:11)
SELECT
GL,
COALESCE( NULLIF(Q4,0), NULLIF(Q3,0), NULLIF(Q2,0), NULLIF(Q1,0) ) as Amount
FROM
myTable
答案 1 :(得分:4)
没有基于SET的方法,因为SQL旨在跨行而不是列进行聚合。
我实际上希望CASE在这里相当快......
CASE WHEN Q4 <> 0 THEN Q4
WHEN Q3 <> 0 THEN Q3
WHEN Q2 <> 0 THEN Q2
WHEN Q1 <> 0 THEN Q1
ELSE NULL
END
然而,有一个替代方法使用NULL和COALESCE ......
COALESCE(NULLIF(Q4, 0), NULLIF(Q3, 0), NULLIF(Q2, 0), NULLIF(Q1, 0))
答案 2 :(得分:1)
案例陈述在这里使用是正确的。这是最有效的选择。
SELECT GL,
CASE
WHEN Q4 != 0 THEN Q4
WHEN Q3 != 0 THEN Q3
WHEN Q2 != 0 THEN Q2
ELSE Q1
END
FROM TheTable
如果您需要基于集合的方法 - 您必须PIVOT然后按RowNumber聚合。那个慢了。
答案 3 :(得分:1)
SELECT
COALESCE(NULLIF(Q4,0),NULLIF(Q3,0),NULLIF(Q2,0),NULLIF(Q1,0))
答案 4 :(得分:1)
基于“Q?”的alpha排序设置based-ish (假设不是所有季度都是0)
with T as (
select GL, Q, VALUE, row_number() over (partition by GL order by Q desc) as row
from (
select GL,Q1,Q2,Q3,Q4 from theTable
) T
unpivot (VALUE for Q in (Q1,Q2,Q3,Q4)) as U
where VALUE <> 0
)
select * from T
where row = 1