是否可以执行左外连接,其中NULL之外的其他内容填充非值?

时间:2016-03-10 18:38:46

标签: sql sql-server tsql database-design

这就是问题所在。 :(

我的表Answers的一列,就像

               Answers
------------------------------------
 id | user_id | question_id |  ans
------------------------------------
 1  |    1    |     1       |   0
 2  |    1    |     2       |  85
 3  |    2    |     1       |   5
 4  |    2    |     2       | NULL

其中ans的值在

范围内
NULL, 0, 5, ..., 95, 100 

NULL表示用户已有效地回答并选择了#34;无回答"。但是,当我LEFT OUTER JOIN Questions表格与Answers时,我无法区分尚未回答的问题以及已回答的问题#34;没有答案"。

那么我是否有办法LEFT OUTER JOIN使用-1代替NULL来填充非值?

(我觉得我不是一个糟糕的数据库设计师......问题是我的项目的要求在周期的后期不断变化。要求就像一个移动的目标。)

6 个答案:

答案 0 :(得分:3)

您需要检查答案表中是否存在不可为空的列,如下所示:

select ..., case when answers.ans is not null then answers.ans 
                 when answers.id is not null then -1 
                 else null 
            end

答案 1 :(得分:3)

是。一种方法使用case语句:

select a.*, (case when a.id is not null then coalesce(ans, -1) end) as ans
from b left join
     a
     on b.answerid = a.id;

我刚刚编写了join条件和列。关键是使用连接键来确定是否存在记录匹配。

答案 2 :(得分:2)

据推测,当成功匹配LEFT JOIN时,该表中的某些列(您正在加入的键)不为空。您的查询可以重构为:

SELECT q.question_id
    ,q.question
    ,CASE WHEN a.question_id IS NOT NULL 
          THEN COALESCE(a.ans, -1)
     END as ans
FROM question q
LEFT JOIN answer a
ON q.question_id = a.question_id

答案 3 :(得分:2)

我不知道您对数据的控制程度如何。不幸的是,选择NULL来表示用户给出的答案,即"没有答案"。这使得非常非常难以区分用户生成的NULL和左外连接操作生成的NULL。如果数据库定义了一个特殊值(例如-1)来表示"用户指定没有答案"并且让NULL代表"缺失值"则可能是好的。别无其他。
使用-1作为特殊值会导致查询中出现一些错综复杂的逻辑,但它并不像现在的混乱那么糟糕。

PS:这并不代表你是一个糟糕的数据库设计师。这只意味着数据库设计有时比我们想象的更微妙。

答案 4 :(得分:1)

这是一个可行的技巧,但它很微妙,需要良好的文档,以便开发人员了解它。

select  u.UserName, q.Question_ID Asked, a.Question_ID Answered, a.Ans
from    Users u
join    Questions q
    on  q.User_ID = u.User_ID
left join Answers a
    on  a.User_ID = u.User_ID
    and a.Question_ID = q.Question_ID
[order by ...];

请注意,我从问题和答案表中调出了Question_ID,而不是单独使用问题表。这意味着当存在用户根本没有回答的问题时,Answered和Ans都将为NULL。如果用户使用"无回答"回答了问题,那么只有Ans将为空。当然,Asked专栏永远不会为空。

UserName   Asked  Answered   Ans
========   =====  ========   ======
Sam        17     17         True      ==> Answer to Q17 is "True"
Sam        18     18         NULL      ==> Answer to Q18 is "no answer"
Sam        19     NULL       NULL      ==> Q19 has not been answered

应用程序中的一点逻辑可以轻松处理这个问题。如果您对尚未回答的问题不感兴趣,请在查询中添加以下内容:

where   a.Question_ID is not null

因此,Ans中的NULL将表示"没有答案" ...但您已经有效地将外部联接转换为内部联接,因此您可以更轻松地将其写入那。然后,我认为你 有兴趣看到所有的问题,并希望区分"没有答案"从没有回答

答案 5 :(得分:-3)

选择...,isnull(ans,-1)

如果这不是您要找的内容,请发布您的选择语句