多个自我联接和空值

时间:2020-09-04 18:28:14

标签: sql sql-server

我敢肯定,这将是一个简单的解决方法,但是我们就在这里。

我有一个表,该表从清单中提取数据,并且我想根据一些问题的答案来构建报告。

表的设置如下:

list_id | QuestionID | Question   | Answer
   1    |     11     | Supervisor?| Jack
   1    |     12     |  Crew 1?   | Sam
   1    |     13     |  Crew 2?   | Sally
   1    |     14     |  Crew 3?   | NULL

可能存在“机组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 个答案:

答案 0 :(得分:2)

要直接回答您的问题,请将问题id过滤器放入联接中...这样,检查是在联接过程中进行的,而不是在联接之后进行(当id为NULL时)。

  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