declare @tx table(
id int identity(1, 1) not null,
data varchar(100),
column1 int,
column2 int,
column3 int
);
insert into
@tx(data, column1, column2, column3)
values
('data1', 1, 2, 3),
('data2', 4, 5, 6),
('data3', 7, 8, null);
select
a.id,
a.data,
c.item,
c.value
from
@tx a
cross apply (
values
(
cast(
(
select
a.* for xml raw
) as xml
)
)
) as b(xmldata)
cross apply (
select
item = xattr.value('local-name(.)', 'varchar(100)'),
value = xattr.value('.', 'int')
from
b.xmldata.nodes('//@*') as xnode(xattr)
where
xnode.xattr.value('local-name(.)', 'varchar(100)') not in
('id', 'data', 'other-columns', 'to-exclude')
) c

SQL Server can't include null values though.
Postgres version:
Note: Should run this first before being able to use hstore functionality: create extension hstore
create temporary table tx(
id int generated by default as identity primary key,
data text,
column1 int,
column2 int,
column3 int
) on commit drop;
insert into
tx(data, column1, column2, column3)
values
('data1', 1, 2, 3),
('data2', 4, 5, 6),
('data3', 7, 8, null);
with a as (
select
id,
data,
each(hstore(tx.*) - 'id'::text - 'data'::text) as h
from
tx
)
select
id,
data,
(h).key as item,
(h).value::int as value
from
a
-- this would work too:
-- where (h).key not in ('id', 'data', 'other-columns', 'to-exclude')

No problem with Postgres, it include nulls
If the number of columns to unpivot is not so dynamic, can do this in Postgres:
select tx.id, tx.data, x.*
from tx
join lateral (
values
('column1', column1),
('column2', column2),
('column3', column3)
) as x(item, value) on true
Equivalent to SQL Server:
select tx.id, tx.data, x.*
from @tx tx
cross apply (
values
('column1', column1),
('column2', column2),
('column3', column3)
) as x(item, value);
Both Postgres and SQL Server include nulls in result
https://stackoverflow.com/questions/55731155/combined-semi-transpose-of-a-data/55731461
No comments:
Post a Comment