Я думаю, вам придется придерживаться объединений, потому что объединения - это точно способ получения результатов, подобных тому, который вы ищете.Цель объединения состоит в том, чтобы объединить наборы строк вместе (при условии или без таковых), и ваш целевой вывод - не что иное, как комбинация подмножеств строк.
Однако, если большинство вопросов всегда имеютединичные ответы позволяют существенно сократить количество необходимых объединений.Идея состоит в том, чтобы объединять только группы с несколькими ответами в виде отдельных наборов строк.Что касается элементов с одним ответом, они объединяются только как часть всего набора данных целевых элементов.
Пример должен лучше иллюстрировать то, что я мог бы плохо описать в устной форме.Предполагая, что в исходных данных есть две потенциально множественные группы ответа: 'q03'
и 'q06'
(фактически, вот исходная таблица:
DECLARE @testTable AS TABLE(
userId int,
itemName varchar(50),
itemValue varchar(255)
);
INSERT INTO @testTable
SELECT 1, 'q01', '1-q01 Answer'
UNION SELECT 1, 'q02', '1-q02 Answer'
UNION SELECT 1, 'q03', '1-q03 Answer 1'
UNION SELECT 1, 'q03', '1-q03 Answer 2'
UNION SELECT 1, 'q03', '1-q03 Answer 3'
UNION SELECT 1, 'q04', '1-q04 Answer'
UNION SELECT 1, 'q05', '1-q05 Answer'
UNION SELECT 1, 'q06', '1-q06 Answer 1'
UNION SELECT 1, 'q06', '1-q06 Answer 2'
UNION SELECT 1, 'q06', '1-q06 Answer 3'
UNION SELECT 2, 'q01', '2-q01 Answer'
UNION SELECT 2, 'q02', '2-q02 Answer'
UNION SELECT 2, 'q03', '2-q03 Answer 1'
UNION SELECT 2, 'q03', '2-q03 Answer 2'
UNION SELECT 2, 'q04', '2-q04 Answer'
UNION SELECT 2, 'q05', '2-q05 Answer'
UNION SELECT 2, 'q06', '2-q06 Answer 1'
UNION SELECT 2, 'q06', '2-q06 Answer 2'
;
, которая совпадает с таблицей в исходном сообщении, нос добавлением 'q06'
элементов) результирующий скрипт может выглядеть так:
WITH ranked AS (
SELECT
*,
rn = ROW_NUMBER() OVER (PARTITION BY userId, itemName ORDER BY itemValue)
FROM @testTable
),
multiplied AS (
SELECT
r.userId,
r.itemName,
r.itemValue,
rn03 = r03.rn,
rn06 = r06.rn
FROM ranked r03
INNER JOIN ranked r06 ON r03.userId = r06.userId AND r06.itemName = 'q06'
INNER JOIN ranked r ON r03.userId = r.userId AND (
r.itemName = 'q03' AND r.rn = r03.rn OR
r.itemName = 'q06' AND r.rn = r06.rn OR
r.itemName NOT IN ('q03', 'q06')
)
WHERE r03.itemName = 'q03'
AND r.itemName IN ('q02', 'q03', 'q05', 'q06')
)
SELECT userId, rn03, rn06, q02, q03, q05, q06
FROM multiplied
PIVOT (
MIN(itemValue)
FOR itemName in (q02, q03, q05, q06)
) AS PivotTable