Нужен SQL запрос для заполнения значений, чтобы в наборе результатов присутствовали все отсутствующие опции - PullRequest
2 голосов
/ 25 марта 2020

У меня есть таблица, которая содержит только необработанные данные: контакт в одном столбце и вариант, который они выбрали в другом, например, так:

Contact Option
A        1
A        3
B        1
C        2
D        3
E        2
E        3

TableOfOptions
1
2
3
4

И я хочу вернуть набор результатов, который имеет контакт для каждого варианта, независимо от того, был ли он выбран. По сути, я хочу «заполнить» набор результатов, используя NULL для не выбранных опций. Таким образом, есть две таблицы, одна с отображением «Выбор контакта», а другая со списком опций. Желаемый набор результатов выглядит следующим образом.

Contact Option Chosen
A       1       1
A       2       NULL
A       3       3
A       4       NULL
B       1       1
B       2       NULL
B       3       NULL
B       4       NULL
C       1       NULL
C       2       2
C       3       NULL
C       4       NULL

Et c, et c, я уверен, что вы поняли. Я не могу понять, как проецировать каждую строку в таблице параметров для каждого контакта в таблице ContactOptions, заполняя недостающие строки значениями NULL для OptionChosen. Каждый «контакт» будет иметь по крайней мере один вариант выбора, некоторые могут иметь несколько, некоторые могут иметь все. Поэтому мне нужно «добавить» между 0 и «n-1» опциями для каждой строки «Контакт», при этом все «добавленные» строки будут равны NULL.

Сначала я использовал CROSS JOIN и имел CASE WHEN x .Option = y.Option затем x.Option else NULL END для третьего столбца ... но я обнаружил, что в некоторых случаях я получаю дублирующиеся строки и не могу понять, почему.

Обратите внимание, что мой пример из реального мира немного сложнее в том смысле, что я хочу перенести гораздо больше свойств, чем просто одно (т. Е. У контакта А есть четыре других свойства, которые я хочу повторить с каждой опцией, но я решил, что это не имеет большого отношения к решение). Но комбинация «Контакт + опция» должна быть уникальной в наборе результатов.

Моя конечная цель - иметь возможность запрашивать заданную опцию, но всегда получать ВСЕ контакты. Например, если я хочу увидеть «Как люди выбрали вариант 2», я хочу, чтобы у каждого от A до E в наборе результатов была ОДНА строка, со значением или NULL в зависимости от того, выбрали ли они параметр или нет.

РЕДАКТИРОВАТЬ : Вот пример кода, который я пробовал, но который приводит к множеству повторяющихся строк, которые мне не нужны:

CREATE TABLE ContactOption ([Contact] CHAR(1), [Option] int);
INSERT INTO ContactOption ([Contact], [Option])
VALUES
('A', 1),
('A', 3),
('B', 1),
('C', 2),
('D', 3),
('E', 2),
('E', 3);

CREATE TABLE TableOfOptions ([Option] int);
INSERT INTO TableOfOptions ([Option])
VALUES
(1),
(2),
(3),
(4);

SELECT co.[Contact],
       t.[Option],
       CASE WHEN co.[Option] = t.[Option] THEN co.[Option] ELSE NULL END AS [Choice]
FROM ContactOption co
     CROSS JOIN TableOfOptions t
ORDER BY co.[Contact], t.[Option]

1 Ответ

1 голос
/ 25 марта 2020

Без таблицы с различными значениями для Contact вам понадобится как минимум 1 DISTINCT здесь, чтобы получить эти DISTINCT значения:

WITH Contacts AS(
    SELECT DISTINCT CO.Contact
    FROM dbo.ContactOption CO)
SELECT C.Contact,
       TOO.[Option],
       CO.[Option]
FROM Contacts C
     CROSS JOIN dbo.TableOfOptions TOO
     LEFT JOIN dbo.ContactOption CO ON C.Contact = CO.Contact
                                   AND TOO.[Option] = CO.[Option];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...