【问题标题】:What SELECT statement will get the non-zero values from table rows?什么 SELECT 语句将从表行中获取非零值?
【发布时间】:2015-08-01 14:41:20
【问题描述】:

如果我在一个 27 列的表中有多行,它们都是这样的整数

id_1    id_2    id_3    id_4    id_5    id_6    id_7    id_8    id_9    id_10   id_11   id_12   id_13   id_14   id_15   id_16   id_17   id_18   id_19   id_20   id_21   id_22   id_23   id_24   id_25   id_26   id_27
0       2       0       4       5       0       0       8       0       10      0       0       0       14      0       0       17      0       0       0       21      0       0       0       0       0       0

我想运行一个 SELECT 语句来获得最多 8 个 > 零的列(永远不会超过 8 个)什么是最好的,或者至少是功能性的方法?如果没有 8 个值 > 0,则允许使用 NULLS。所以上面的结果表是。

col1 col2 col3 col4 col5 col6 col7 col8
2    4    5    8    10   14   17   21

【问题讨论】:

  • 我认为我们可以通过程序来实现它
  • 您想要每行 8 个值还是所有行 8 个值?如果是每行,你有行标识符吗?
  • @GordonLinoff 没有标识符,但它是一个临时表,因此我可以在必要时添加一个。每行有 8 个值。

标签: sql tsql sql-server-2005


【解决方案1】:

如果您可以忍受将结果放在列中,那么这是一种简单的方法:

select top 8 v.col
from table t cross apply
     values ((t.id_1), (t.id_2), . . ., (t.id_27)) as v(col)
where v.col <> 0;

所有数据都为 8。如果你想要每行 8 个,那么你需要一个行标识符。你可以使用窗口函数:

select t.id, v.col
from (select t.id, v.col,
             row_number() over (partition by t.id order by (select null)) as seqnum
      from table t cross apply
           values ((t.id_1), (t.id_2), . . ., (t.id_27)) as v(col)
      where col <> 0
     ) t
where seqnum <= 8;

最后,您可以将它们转回单行。我倾向于使用条件聚合来做到这一点:

select t.id,
       max(case when seqnum = 1 then v.col end) as val1,
       max(case when seqnum = 2 then v.col end) as val2,
       max(case when seqnum = 3 then v.col end) as val3,
       max(case when seqnum = 4 then v.col end) as val4,
       max(case when seqnum = 5 then v.col end) as val5,
       max(case when seqnum = 6 then v.col end) as val6,
       max(case when seqnum = 7 then v.col end) as val7,
       max(case when seqnum = 8 then v.col end) as val8
from (select t.id, v.col,
             row_number() over (partition by t.id order by (select null)) as seqnum
      from table t cross apply
           values ((t.id_1), (t.id_2), . . ., (t.id_27)) as v(col)
      where col <> 0
     ) t
where seqnum <= 8
group by id;

【讨论】:

  • 我遇到语法错误。我现在添加了一个名为 id 的标识符,我的表名为 tester。请问这将如何改变你的脚本?
猜你喜欢
  • 1970-01-01
  • 2011-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多