T SQL条件连接

时间:2018-04-12 08:42:12

标签: tsql left-join

原谅我的语言,英语不是我的母语。

存在以下情况:

一个对象,为了简单起见,我们称之为公寓,可以(但不一定)引用我们现在称之为house的同类型的父对象。

公寓可能有一个地址(其他表格),如果不是,房子的地址是相关的。

为此我尝试建立一个连接,它返回公寓的地址(如果有的话)或房子的地址。

我之前的做法:

    LEFT OUTER JOIN
    dbo.stelle_adressen AS ADR_Default ON 
        (ADR_Default.stelle_id = stelle.stelle_id 
         AND ADR_Default.adress_typ_id = 1 
         AND ADR_Default.aktiv = 1)
        OR
        (ADR_Default.stelle_id = stelle.referenz_id 
         AND ADR_Default.adress_typ_id = 1 
         AND ADR_Default.aktiv = 1)

同样有效,只是不需要,因为如果存在住房地址,也会形成住宅地址的连接,因此会传递2行。

有什么建议吗?

简化查询:

SELECT        
    stelle.stelle_id, 
    ADR_DOBJ.adr_objekt_id, 
    ADR_STR.strasse, 
    ADR_STR.plz, 
    ADR_STR.ort, 
    ADR_DOBJ.hausnummer, 
    ADR_Default.aktiv
FROM            
    stelle 
    INNER JOIN
    stelle_adressen AS ADR_Default ON  
    (ADR_Default.stelle_id = stelle.stelle_id AND ADR_Default.adress_typ_id = 1 AND ADR_Default.aktiv = 1) 
    OR 
    (ADR_Default.stelle_id = stelle.referenz_id AND ADR_Default.adress_typ_id = 1 AND ADR_Default.aktiv = 1) 
    LEFT OUTER JOIN
    adr_objekt AS ADR_DOBJ ON ADR_DOBJ.adr_objekt_id = ADR_Default.adr_objekt_id 
    LEFT OUTER JOIN
    adr_objekt_strassen AS ADR_STR ON ADR_STR.strasse_id = ADR_DOBJ.strasse_id
WHERE stelle.stelle_id = 2

结果:

stelle_id   adr_objekt_id   strasse plz ort hausnummer  aktiv
2   8   Walterhöferstraße   14165   Berlin  11  1
2   1   Gustav-Adolf-Straße 13086   Berlin  106a    1

预期结果:

stelle_id   adr_objekt_id   strasse plz ort hausnummer  aktiv
2   8   Walterhöferstraße   14165   Berlin  11  1

查询返回2行,其中一行有自己的地址,另一行有引用的对象地址(只有在没有自己的地址可用的情况下才会返回)

1 个答案:

答案 0 :(得分:0)

作为变体,您可以尝试将TOP 1ORDER BY

一起使用
SELECT TOP 1
    stelle.stelle_id, 
    ADR_DOBJ.adr_objekt_id, 
    ADR_STR.strasse, 
    ADR_STR.plz, 
    ADR_STR.ort, 
    ADR_DOBJ.hausnummer, 
    ADR_Default.aktiv
FROM stelle 
JOIN stelle_adressen AS ADR_Default ON
      ADR_Default.adress_typ_id = 1 AND ADR_Default.aktiv = 1
  AND (ADR_Default.stelle_id = stelle.stelle_id OR ADR_Default.stelle_id = stelle.referenz_id) 
LEFT JOIN
    adr_objekt AS ADR_DOBJ ON ADR_DOBJ.adr_objekt_id = ADR_Default.adr_objekt_id 
LEFT JOIN
    adr_objekt_strassen AS ADR_STR ON ADR_STR.strasse_id = ADR_DOBJ.strasse_id
WHERE stelle.stelle_id = 2
ORDER BY IIF(ADR_Default.stelle_id = stelle.referenz_id,2,1)

stelle.stelle_id的优先级为1,stelle.referenz_id为2。

你是否总想只获得一排? 条件WHERE stelle.stelle_id = 2是否始终使用?

如果您想获取多个stelle_id的地址,可以尝试以下

SELECT *
FROM
  (
    SELECT
        stelle.stelle_id, 
        ADR_DOBJ.adr_objekt_id, 
        ADR_STR.strasse, 
        ADR_STR.plz, 
        ADR_STR.ort, 
        ADR_DOBJ.hausnummer, 
        ADR_Default.aktiv,
        ROW_NUMBER()OVER(PARTITION BY stelle.stelle_id ORDER BY IIF(ADR_Default.stelle_id = stelle.referenz_id,2,1)) N
    FROM stelle 
    JOIN stelle_adressen AS ADR_Default ON
          ADR_Default.adress_typ_id = 1 AND ADR_Default.aktiv = 1
      AND (ADR_Default.stelle_id = stelle.stelle_id OR ADR_Default.stelle_id = stelle.referenz_id) 
    LEFT JOIN
        adr_objekt AS ADR_DOBJ ON ADR_DOBJ.adr_objekt_id = ADR_Default.adr_objekt_id 
    LEFT JOIN
        adr_objekt_strassen AS ADR_STR ON ADR_STR.strasse_id = ADR_DOBJ.strasse_id
    --WHERE stelle.stelle_id = 2
  ) q
WHERE N=1

我在这里评论了条件WHERE stelle.stelle_id = 2

PS。我认为您也可以使用条件AND ADR_Default.stelle_id IN(stelle.stelle_id,stelle.referenz_id)代替AND (ADR_Default.stelle_id = stelle.stelle_id OR ADR_Default.stelle_id = stelle.referenz_id)