#sql #sql-server
#sql #sql-сервер
Вопрос:
Я уверен, что это будет легко исправить, но мы здесь.
У меня есть таблица, которая извлекает данные из контрольного списка, и я хочу создать отчет на основе ответов на несколько вопросов.
Стол накрыт вот так:
list_id | QuestionID | Question | Answer
1 | 11 | Supervisor?| Jack
1 | 12 | Crew 1? | Sam
1 | 13 | Crew 2? | Sally
1 | 14 | Crew 3? | NULL
Потенциально существует ‘Crew 3?’, но обычно это null, то же самое с Crew 2, если на то пошло. Теперь я хочу, чтобы Отчет выглядел следующим образом:
Supervisor | Crew 1 | Crew 2 | Crew 3
Но когда я использую левое соединение для самостоятельного соединения с таблицей, я получаю только те результаты, которые включают все три команды, и исключаю все экземпляры, где есть нулевые поля.
Моя текущая попытка:
SELECT
sup.Answer AS 'Sup'
,C1.Answer AS '1'
,C2.Answer AS '2'
,C3.Answer AS '3'
FROM ChecklistDetail AS sup
LEFT JOIN ChecklistDetail AS C1
ON C1.listID =sup.listID
LEFT JOIN ChecklistDetail AS C2
ON C2.listID =sup.listID
LEFT JOIN ChecklistDetail AS C3
ON C3.listID =sup.listID
WHERE
sup.QuestionID = 11
AND C1.QuestionID = 12
AND C2.QuestionID = 13
AND C3.QuestionID = 14
Вероятно, это что-то очевидное, но я наткнулся на кирпичную стену, просматривая Google и находя кучу довольно близких ответов, которые не совсем работают. Будем признательны за любую помощь!
Комментарии:
1. О! Мои извинения, первый пост и все такое. Я использую SQL-Server Management Studio.
Ответ №1:
Чтобы ответить на ваш вопрос напрямую, вставьте фильтры идентификаторов вопросов в объединения… Таким образом, проверка выполняется во время объединения, а не после него (когда идентификатор может быть нулевым).
SELECT
sup.Answer AS 'Sup'
,C1.Answer AS '1'
,C2.Answer AS '2'
,C3.Answer AS '3'
FROM ChecklistDetail AS sup
LEFT JOIN ChecklistDetail AS C1
ON C1.listID =sup.listID
AND C1.QuestionID = 12
LEFT JOIN ChecklistDetail AS C2
ON C2.listID =sup.listID
AND C2.QuestionID = 13
LEFT JOIN ChecklistDetail AS C3
ON C3.listID =sup.listID
AND C3.QuestionID = 14
WHERE
sup.QuestionID = 11
Однако лучшим способом может быть условное агрегирование…
SELECT
ListID,
MAX(CASE WHEN QuestionID = 11 THEN Answer END) AS 'sup',
MAX(CASE WHEN QuestionID = 12 THEN Answer END) AS '1',
MAX(CASE WHEN QuestionID = 13 THEN Answer END) AS '2',
MAX(CASE WHEN QuestionID = 14 THEN Answer END) AS '3'
FROM
ChecklistDetail
WHERE
QuestionID IN (11,12,13,14)
GROUP BY
ListID
Комментарии:
1. Ааааааннд, это было так просто! Большое вам спасибо! Мне придется изучить условную агрегацию, но пока это, безусловно, сработает.
2. @zacwatkins Теперь я добавил SQL с условной агрегацией (кроме того, загляните в PIVOT, хотя мне это не нравится, и я предпочитаю условную агрегацию, за мои грехи)