SQL Server отключить несколько столбцов
Я пытаюсь развернуть таблицу вокруг множества столбцов, чтобы получить 3 столбца (сводка, имя столбца, значение)
так например:
name | age | gender
------+-------+---------
John | 20 | M
Jill | 21 | F
станет:
name | column | value
-----+--------+-------
John | age | 20
John | gender | M
Jill | age | 21
Jill | gender | F
Я немного погуглил, но не нашел подобной ситуации - тем более, что разворот, кажется, делается в противоположном направлении, чем то, что я пытаюсь достичь.
4 ответа
Преобразование столбцов в строки называется UNPIVOT
, Вы не указали, какую версию SQL Server вы используете, но есть несколько разных способов получить результат.
Ты можешь использовать SELECT
с UNION ALL
:
SELECT name, 'age' as column, cast(age as varchar(10)) as value
FROM yourtable
UNION ALL
SELECT name, 'gender' as column, gender as value
FROM yourtable;
Если вы используете SQL Server 2005+, вы можете использовать функцию UNPIVOT:
SELECT name, column, age
FROM
(
SELECT
name,
age = cast(age as varchar(10)),
gender
FROM yourtable
) d
UNPIVOT
(
value
for column in (age, gender)
) unpiv;
Наконец, вместо функции UNPIVOT вы также можете использовать CROSS APPLY
либо с VALUES
(2008+) или UNION ALL
:
SELECT name, column, age
FROM yourtable
CROSS APPLY
(
VALUES
('age', cast(age as varchar(10)),
('gender', gender)
) c (column, value);
Любая из этих версий даст вам желаемый результат. Вы заметите, что я должен был бросить age
столбец к varchar
, Это связано с тем, что тип данных / длина (в непивотном направлении) столбцов должны быть одинаковыми, поскольку в конечном результате вы будете преобразовывать их в один столбец.
SELECT name, column, value
FROM (SELECT name, age, gender
FROM table) src
UNPIVOT (value FOR column IN (age, gender)) pvt
Вы можете легко сделать это с помощью предложения 'WITH' и сгенерированного вспомогательного столбца. В
первом cte вы создаете временный столбец, во втором вы его разворачиваете, а в третьем снова собираете. Вуаля!
WITH cte1 AS (SELECT ROW_NUMBER() OVER (ORDER BY adl_id, ma_id) AS rk,
adl_id,
ma_id,
ISNULL(CONVERT(CHAR,fosa_id),'') fosa_id,
ISNULL(CONVERT(CHAR,kdah_id),'') kdah_id,
ISNULL(CONVERT(CHAR,lb_id),'') lb_id,
ISNULL(CONVERT(CHAR,sprach_id),'') sprach_id
FROM tm_lieferant WHERE adl_id=1004)
,cte2 AS (SELECT rk, fieldname, [value] FROM (
SELECT rk, fosa_id, kdah_id, lb_id, sprach_id FROM cte1 ) p
UNPIVOT([value] FOR fieldname IN (fosa_id, kdah_id, lb_id, sprach_id
)) AS unpvt)
,cte3 AS (SELECT cte1.adl_id, cte1.ma_id, cte2.fieldname, cte2.value FROM cte2 INNER JOIN cte1 ON cte2.rk=cte1.rk)
SELECT * FROM cte3