display rows as columns
(1) By anonymous on 2022-04-01 19:41:38 [link] [source]
hi! I have a table like this: id name 4 PRO7 4 ProSieben 5 RTL 6 kabel eins 6 KABEL1 7 RTL II 7 RTL2 8 ARTE ... How can I display it this way: id name1 name2 4 PRO7 ProSieben 5 RTL 6 kabel eins KABEL1 7 RTL II RTL2 8 ARTE ... There are not more than 2 names per id ! thanks Peter
(2) By Gerry Snyder (GSnyder) on 2022-04-01 20:52:13 in reply to 1 [link] [source]
Look at GROUP BY and the GROUP_BY() function.
Gerry
(3) By anonymous on 2022-04-01 21:03:01 in reply to 2 [link] [source]
hm - sorry but I can't see how GROUP BY could help.
(5) By Gerry Snyder (GSnyder) on 2022-04-01 21:55:12 in reply to 3 [link] [source]
Sorry, I meant "GROUP_CONCAT()"
(4.1) By Keith Medcalf (kmedcalf) on 2022-04-01 21:46:17 edited from 4.0 in reply to 1 [link] [source]
last=-1
first=1
EXEC SQL SELECT id, name FROM t
WHILE (!END OF ROWS)
FETCH INTO :id, :name
if id != last
last = id
if first
first=0
print "id", "name1", "name2"
else
print
end
print id, name,
else
print name,
end
LOOP
print
(6.1) By Keith Medcalf (kmedcalf) on 2022-04-01 22:06:56 edited from 6.0 in reply to 4.1 [link] [source]
Then, of course, you may have misstated your goal and instead of wanting to know how to "display" the data, you want to make a new table-form (which is, obviously, quite a different thing from "display"):
create table t
(
id integer not null,
name text not null
);
insert into t values
(4,'PRO7'),
(4,'ProSieben'),
(5,'RTL'),
(6,'kabel eins'),
(6,'KABEL1'),
(7,'RTL II'),
(7,'RTL2'),
(8,'ARTE');
select id,
max(iif(cn == 1, name, NULL)) as name1,
max(iif(cn == 2, name, NULL)) as name2
from (
select id,
row_number() over (partition by id) as cn,
name
from t
)
group by id;
(7) By anonymous on 2022-04-01 22:19:14 in reply to 6.1 [link] [source]
Beautiful. You beat me to it :D
It's called a PIVOT operation:
https://oracle-base.com/articles/11g/pivot-and-unpivot-operators-11gr1
For the record, since I typed it as well:
with
DataSet
as
(
select 4 as id, 'PRO7' as name union all
select 4 as id, 'ProSieben' as name union all
select 5 as id, 'RTL' as name union all
select 6 as id, 'kabel eins' as name union all
select 6 as id, 'KABEL1' as name union all
select 7 as id, 'RTL II' as name union all
select 7 as id, 'RTL2' as name union all
select 8 as id, 'ARTE' as name
),
ResultSet
as
(
select DataSet.*,
row_number() over( partition by id order by name ) as rn
from DataSet
)
select ResultSet.id,
max( case when ResultSet.rn = 1 then ResultSet.name end ) as name1,
max( case when ResultSet.rn = 2 then ResultSet.name end ) as name2
from ResultSet
group by ResultSet.id
order by ResultSet.id;
4|PRO7|ProSieben
5|RTL|
6|KABEL1|kabel eins
7|RTL II|RTL2
8|ARTE|
(11) By midijohnny on 2022-05-10 22:29:32 in reply to 7 [link] [source]
This is a nice answer and works really well. I'm just trying to understand how it works.
The thing that is confusing me is the purpose of the 'max' function - I note that I can swap it out for a 'min' or 'group_concat' function - and everything continues to work.
So is the use of 'max' (or 'min', 'group_concat') just a way of fitting-in with the group-by ?
Thanks !
(12) By Keith Medcalf (kmedcalf) on 2022-05-10 23:48:12 in reply to 11 [link] [source]
You are using a group by, and each "group" contains one value for each column somewhere amongst the group, and null everywhere else. The aggregate ignores null values so will return only the one value (which is also the min and the max and group_concat and perhaps others (that is, aggregates that return one (or only) of the non-null values provided)).
(13.1) By midijohnny on 2022-05-15 12:22:04 edited from 13.0 in reply to 12 [source]
Thanks for the explanation; still seems like a bit of a trick, but works nicely enough.
I made a modified version for the sake of it - since we are already using a WINDOW function - we can make use of the lead function.
with
DataSet
as
(
select 4 as id, 'PRO7' as name union all
select 4 as id, 'ProSieben' as name union all
select 5 as id, 'RTL' as name union all
select 6 as id, 'kabel eins' as name union all
select 6 as id, 'KABEL1' as name union all
select 7 as id, 'RTL II' as name union all
select 7 as id, 'RTL2' as name union all
select 8 as id, 'ARTE' as name
),
ResultSet
AS
(
SELECT DataSet.*,
row_number() OVER w1 AS rn,
lead(name,0) OVER w1 AS name1,
lead(name,1) OVER w1 AS name2
FROM DataSet
WINDOW w1 AS ( PARTITION BY id ORDER BY name )
) SELECT id,name1,name2 FROM resultset WHERE rn=1
Output:
id name1 name2
4 PRO7 ProSieben
5 RTL
6 KABEL1 kabel eins
7 RTL II RTL2
8 ARTE
(8) By anonymous on 2022-04-02 21:34:24 in reply to 6.1 [link] [source]
Thanks, that works perfectly.
(10) By Vadim Goncharov (nuclight) on 2022-05-07 22:55:41 in reply to 4.1 [link] [source]
Do SQLite allows such syntax?
(9) By anonymous on 2022-04-02 21:35:56 in reply to 1 [link] [source]
Thanks to all for your input.