【问题标题】:SQL Join to include NULL valuesSQL 连接以包含 NULL 值
【发布时间】:2014-10-21 09:19:09
【问题描述】:

我正在尝试将 3 个表加入到一个 select 语句中,但计算一个表的出现次数,同时在没有出现的情况下仍然显示记录。

可以在我整理的快速 sqlFiddle 中看到我的示例。我尝试使用左连接,但它没有产生我想要的结果。

http://sqlfiddle.com/#!6/e2840/8

这是 SQL 语句:

SELECT O.OptionID,O.OptionName, Count(A.OptionID) AS Total
FROM Options as O
    LEFT JOIN Answers AS A  ON O.OptionID = A.OptionID 
    LEFT JOIN Users as U ON A.UserId = U.UserID  
WHERE   A.QuestionID = 1
GROUP BY O.OptionID,O.OptionName

我希望它返回选项表中的所有行,如果没有找到该选项的答案,则在总列中显示 0。

当前小提琴返回的内容:

我希望它返回什么:

【问题讨论】:

  • 为什么没有人指出不需要用户?
  • 你是对的,在这个例子中不需要它,但我把它包括在内,因为在我的现实生活中,它是必不可少的。

标签: sql sql-server join sql-server-2012


【解决方案1】:

选择答案:

SELECT O.OptionID,O.OptionName, Count(A.OptionID) AS Total
FROM Options as O
LEFT JOIN 
(
    SELECT OPTIONID,USERID 
    FROM Answers WHERE QuestionID = 1
) AS A  ON O.OptionID = A.OptionID 
LEFT JOIN Users as U ON A.UserId = U.UserID  
GROUP BY O.OptionID,O.OptionName

【讨论】:

    【解决方案2】:

    您正在使用带有 LEFT JOIN 的 WHERE 子句,这使它的行为类似于 INNER JOIN。

    试试这个:

    SELECT O.OptionID, O.OptionName, Count(A.OptionID) AS Total
    FROM Options as O
        LEFT JOIN Answers AS A  ON O.OptionID = A.OptionID 
        and A.QuestionID = 1
        LEFT JOIN Users as U ON A.UserId = U.UserID  
    GROUP BY O.OptionID,O.OptionName
    

    【讨论】:

    • 这确实有效,但我在 answers 表中有 2 亿条记录,where 子句对于触发索引至关重要。按照自己的方式进行操作,它实际上根本不会加载到实时数据库上。我该如何解决这个问题?谢谢!
    • 使用子选择,将answers as A替换为(SELECT OPTIONID,USERID FROM Answers WHERE QuestionID = 1) AS A
    【解决方案3】:

    试试下面的方法...

           SELECT O.OptionID,O.OptionName, Count(A.OptionID) AS Total
           FROM Options as O
           LEFT JOIN Answers AS A  ON O.OptionID = A.OptionID and A.questionId=1
           LEFT JOIN Users as U ON A.UserId = U.UserID  
           GROUP BY O.OptionID,O.OptionName
    

    【讨论】:

      【解决方案4】:

      未引用用户表,这与使用 sqlfiddle 中的数据匹配的预期结果。

      SELECT O.OptionID,O.OptionName, Count(A.OptionID) AS Total
      FROM Options as O
          LEFT JOIN Answers AS A  ON O.OptionID = A.OptionID
                                  AND A.QuestionID = 1
      GROUP BY O.OptionID,O.OptionName
      

      顺便说一句:使用子查询不会获得任何好处。添加的连接条件执行完全相同的工作。

      但是避免冗余连接会获得优势。

      【讨论】:

        【解决方案5】:

        与@mjsqu 相同,但会避免使用子集。这是在没有子集的情况下加入的更好方法

        SELECT O.OptionID,O.OptionName, Count(A.OptionID) AS Total
        FROM Options as O
            LEFT JOIN Answers AS A  ON O.OptionID = A.OptionID and A.QuestionID = 1
            LEFT JOIN Users as U ON A.UserId = U.UserID  
        GROUP BY O.OptionID,O.OptionName
        

        【讨论】:

          猜你喜欢
          • 2016-05-11
          • 2018-10-25
          • 1970-01-01
          • 2023-02-03
          • 2012-01-04
          • 2014-08-29
          • 1970-01-01
          • 2020-02-08
          • 1970-01-01
          相关资源
          最近更新 更多