Конвертировать строки в столбцы в SQL - PullRequest
2 голосов
/ 25 июля 2011

Таблица A

ID  COLA    
-----------------------
A   value1      
B   value1
C   value1      

Таблица B

ID  DETAIL_ID   COL_X   COL_Y
A   0           foo     foo
A   1           bar     bar
B   0           foo     foo

Мой ожидаемый выход - что-то вроде

ID  COLA    COL_X_0 COL_X_1 COL_Y_0 COL_Y_1
A   value1  foo     bar     foo     bar
B   value1  foo     NULL    foo     NULL
C   value1  NULL    NULL    NULL    NULL

Это означает, что строки таблицы B будут значениями столбцов на основе столбца DETAIL_ID.

Я пытался написать запросы для этого, но не удалось из-за следующего. Количество значений DetailID НЕ будет фиксированной длиной. Это означает, что я не могу жестко закодировать название столбцов.

Ответы [ 3 ]

1 голос
/ 26 июля 2011

Это даст точный результат, который вы описали, и вы можете добавить больше столбцов, если необходимо

DECLARE @a table (id char, cola varchar(10))
DECLARE @b table (id char, detail_id int, colx char(3), coly char(3))

INSERT @a values('A', 'value1'),('B', 'value2'),('C','value3')
INSERT @b values('A', 0, 'foo', 'foo'),('A', 1, 'bar', 'bar'),
('B',0, 'foo','foo')--,('A', 2, 'bar', 'bar') -- add this for extra columns

CREATE TABLE ##t(id char, detail_id tinyint, colvalue char(3), col varchar(8), cola varchar(10))
DECLARE @columns varchar(max)=''
DECLARE @sqlstring varchar(1000)

;WITH a as (
SELECT a.id, a.cola, b.detail_id, colx, coly,
'col_x_' + cast(detail_id as varchar) col_a,
'col_y_' + cast(detail_id as varchar) col_b
FROM @a a LEFT JOIN @b b on a.id = b.id
) 
INSERT ##t
SELECT id, detail_id, colx, col_a, cola FROM a
UNION
SELECT id, detail_id, coly, col_b, cola FROM a
ORDER BY 4,2

SELECT @columns = coalesce(@columns, '') +',[' + col + ']'
FROM (
SELECT DISTINCT col, detail_id FROM ##t where not col is null
) a 

SET @columns = stuff(@columns, 1,1,'')

SET @sqlstring = 
'SELECT * FROM (
SELECT id, cola, col, colvalue FROM ##t 
) b
PIVOT(max(colvalue) FOR col 
in(
'+@columns+'))AS p order by 1'

EXEC(@sqlstring)

DROP TABLE ##t
0 голосов
/ 26 июля 2011

В запросах SQL должны быть указаны столбцы набора результатов. Это фундаментально для SQL. Даже PIVOT требует, чтобы в вашем запросе были указаны столбцы перед его отправкой в ​​СУБД.

По этой причине сложно и подвержено ошибкам создание запроса, который возвращает строки в виде столбцов, как вы описываете, и может при необходимости адаптироваться к любому количеству столбцов.

Обработка динамических столбцов должна выполняться в два этапа.

Один из вариантов - сделать следующие два этапа:

  1. Напишите код приложения для динамического построения SQL-запроса на основе различных значений, найденных в данных. Это требует дополнительного запроса, чтобы выяснить, какие значения существуют, чтобы вы могли построить запрос.
  2. Выполнить запрос SQL и получить результаты.

Другой вариант - сделать следующие два этапа:

  1. Запустите более простой запрос SQL, который выбирает строки как строки, так как они хранятся в базе данных.
  2. Написать код приложения для последующей обработки результатов, собирая отдельные значения из строк в расширяющийся набор столбцов на основе найденных значений. Это не требует дополнительного запроса, как первый дизайн.
0 голосов
/ 25 июля 2011

Просто объедините таблицы A и B на B.DETAIL_ID == A.ID ?? Или это слишком просто?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...