有条件的内部加入

时间:2011-09-01 09:43:55

标签: sql sql-server tsql join inner-join

我希望能够根据表达式的结果内部连接两个表。

到目前为止我一直在努力:

INNER JOIN CASE WHEN RegT.Type = 1 THEN TimeRegistration ELSE DrivingRegistration AS RReg
ON
RReg.RegistreringsId = R.Id

RegT是我在此加入之前创建的联接:

INNER JOIN RegistrationTypes AS RegT ON R.RegistrationTypeId = RegT.Id

此SQL脚本不起作用。

总而言之,如果Type为1,那么它应该加入表TimeRegistration,否则它应该加入DrivingRegistration

解决方案:

在我的select语句中,我执行了以下连接:

INNER JOIN  RegistrationTypes AS RegT ON R.RegistrationTypeId = RegT.Id
LEFT OUTER JOIN TimeRegistration AS TReg ON TReg.RegistreringsId = R.Id AND RegT.Type = 1
LEFT OUTER JOIN DrivingRegistration AS DReg ON DReg.RegistreringsId = R.Id AND RegT.Type <>1

然后我编辑了我的where-clause以输出正确的内容,具体取决于RegType,如下所示:

WHERE (CASE RegT.Type WHEN 1 THEN TReg.RegistreringsId ELSE DReg.RegistreringsId END = R.Id)

4 个答案:

答案 0 :(得分:19)

尝试使用LEFT JOIN

将两个表放入查询中
LEFT JOIN TimeRegistration TR ON r.rid = TR.Id AND RegT.type =1 
LEFT JOIN DrivingRegistration DR ON r.rid = DR.Id AND RegT.type <>1 

现在,在你的select子句中,使用

CASE RegType.Type WHEN 1 THEN TR.SomeField ELSE DR.someField END as SomeField

另一种选择是使用动态SQL

答案 1 :(得分:8)

您可能需要执行两个左连接,一个连接到TimeRegistration,一个连接到DrivingRegistration,然后从相应的连接表返回所需的字段,如下所示:

LEFT JOIN TimeRegistration ON TimeRegistration.RegistreringsId = R.Id
LEFT JOIN DrivingRegistration ON DrivingRegistration.RegistreringsId = R.Id

你选择语句会是这样的:

SELECT CASE WHEN RegT.Type = 1 THEN TimeRegistration.Foo ELSE DrivingRegistration.Bar END

我喜欢你想要做的事情,但我认为SQL并不聪明。

答案 2 :(得分:1)

SELECT
  R.foo, tr.bar
FROM
  SomeTable AS R
  INNER JOIN RegistrationTypes AS RegT ON R.RegistrationTypeId = RegT.Id 
                                          AND RegT1.Type = 1
  INNER JOIN TimeRegistration AS tr    ON /* whatever */

UNION 

SELECT
  R.foo, dr.bar
FROM
  SomeTable AS R
  INNER JOIN RegistrationTypes AS RegT ON R.RegistrationTypeId = RegT.Id 
                                          AND RegT1.Type = 2
  INNER JOIN DrivingRegistration AS dr ON /* whatever */

答案 3 :(得分:0)

所以我有一个场景,在一个表中有三个电子邮件列(不要问为什么),它们中的任何一个都可以为空(或为空)。在此示例代码中,我将处理它为null的情况。

我必须通过任何电子邮件将其添加到另一个表中,以检索用户的名字。

这是起作用的

select  

m.email1,
m.email2,
m.email3, 
m2.firstName

from MyTable m

left join MyOtherTable m2 on m2.Email = 
case when m.email1 is null then 

    case when m.email2 is null then 

        case when m.email3 null then 
            'nonexistent@mydomain.com' -- i stopped here
        else m.email3 end

    else wm.email2 end

else m.email1 end

很明显,您将包括进一步的条件,例如

case when m.email1 is null or m.email1 = '' then ...

覆盖空值。