Click here to Skip to main content
15,887,394 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
How to remove null values and display non-null values in multiple rows


col1 col2 col3
ann null null
null dev null
null null ora
null null own
add null null
null dig null

output
col1 col2 col3
ann dev ora
add dig own

What I have tried:

expected output
col1 col2 col3
ann dev ora
add dig own
Posted
Comments
[no name] 25-Jan-24 11:47am    
Your question assumes SQL is a feasible and practical tool for this task. I'm not so sure based on the limited info.

1 solution

Your problem is that you have nothing that links the items together. Just because you enter the data in that particular order, does not mean that SQL will return it in that order when you do a select *
You need an addtional column that helps you e.g.
SQL
declare @demo table (col1 varchar(30), col2 varchar(30), col3 varchar(30), partitioner int);
insert into @demo (col1,col2,col3,partitioner) values
('ann', null, null,0),
(null, 'dev', null,0),
(null, null, 'ora',0),
(null, null, 'own',1),
('add', null, null,1),
(null, 'dig', null,1);
In this data I have introduced a column partitioner where I have explicitly indicated which rows need to be collated. The problem then becomes trivial
SQL
select max(col1) as col1, max(col2) as col2, max(col3) as col3
from @demo
group by partitioner;
If we have a row number available then we could do something like this
SQL
;;;with cte as
(
	select col1, col2, col3, rn, cast((rn - 1)  / 3 as int) as partitioner
	from @demo
)
select max(col1) as col1, max(col2) as col2, max(col3) as col3
from cte
group by partitioner;
The row number would have to be defined in the table e.g.
SQL
declare @demo table (col1 varchar(30), col2 varchar(30), col3 varchar(30), rn int identity(1,1));
because we can't use the row_number() function without something to sort by. Unless of course you have some other column such as datetimeInserted
Here partitioner is calculated with cast((rn - 1) / 3 as int) which for row numbers 1,2,3,4,5 and 6 generates 0,0,0,1,1 and 1 like the first example.

Edit: N.B. This method relies on the identity column generating sequential numbers, no gaps. This is not guaranteed to be the case. It would be better to have rn as "something that you can order the table by" e.g. that datetime the row was inserted I mentioned above. Then you can guarantee sequential numbers with
SQL
((row_number() over (order by rn)) -1 ) / 3 as partitioner
 
Share this answer
 
v2
Comments
Maciej Los 2-Feb-24 12:29pm    
5ed!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900