Which SELECT statement will get non-null values ββfrom table rows?
If I have multiple rows in a 27 column table that are integers like
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
and I wanted to run a SELECT statement to get a maximum of 8 columns that are zero (there will never be more than 8 of them), what would be the best, or at least functional way of doing this? In the absence of 8 values> 0, NULLS are allowed. So the summary table from above will be.
col1 col2 col3 col4 col5 col6 col7 col8
2 4 5 8 10 14 17 21
+3
source to share
1 answer
If you can carry the results that are in a column, then this is an easy way:
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;
This gets 8 for all data. If you need 8 lines, you need a line id. And you can use window functions:
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;
Finally, you can flip them back to one line. I tend to do this using conditional aggregation:
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;
+5
source to share