显式连接语法

问题描述 投票:1回答:2

我正在增强一个旧的应用程序,该应用程序使用与以下类似的查询。我想将语法转换为开始使用显式JOIN语法。以下是“显式联接语法”查询:

Select
       DTL.DetailId
     , HDR.PersonId
from
       CMPN.Header             HDR
     , CMPN.Detail             DTL
     , CMPN.DetailStatus       DST
     , CMPN.AdjustmentsDetails CAD
where
       HDR.HeaderId                      = DTL.HeaderId
       and DTL.DetailId                  = DST.DetailId
       and DTL.DetailId                  = CAD.DetailId
       and DST.DetailStatusCode          = 'Approved'
       and DST.ExpirationTimestamp IS NULL
       and HDR.Group                     = 'Group A'
;
sql sql-server inner-join
2个回答
4
投票

尝试一下:

SELECT
    DTL.DetailId, HDR.PersonId
FROM
    CMPN.Header HDR
INNER JOIN
    CMPN.Detail DTL ON HDR.HeaderId = DTL.HeaderId
INNER JOIN
    CMPN.DetailStatus DST ON DTL.DetailId = DST.DetailId
INNER JOIN
    CMPN.AdjustmentsDetails CAD ON DTL.DetailId = CAD.DetailId
WHERE
    DST.DetailStatusCode = 'Approved'
    AND DST.ExpirationTimestamp IS NULL
    AND HDR.Group = 'Group A';

1
投票

您正在显示一个具有1980年代样式的联接的查询,并希望将它们更改为显式联接,这是一个好主意。但是联接并不是表示查询中关系的唯一方法。

在您的情况下,您正在从两个表中选择数据,但是涉及到第三个表。当header中存在某个条目时,您只想从detaildetailstatus中选择数据。当我们要检查条目是否存在时,通常使用EXISTSIN子句。这也将它所属的第三个表放在WHERE子句中,因为它只代表一个条件。

这是我写查询的方式:

SELECT dtl.detailid, hdr.personid
FROM cmpn.header hdr
JOIN cmpn.detail dtl ON dtl.headerid = hdr.headerid
WHERE hdr.group = 'Group A'
AND dtl.detailid IN
(
  SELECT detailid
  FROM cmpn.detailstatus
  WHERE detailstatuscode = 'Approved'
  AND expirationtimestamp IS NULL
);

此查询的读者一眼便会看到,它不会产生重复项,原始查询则不会这样,在原始查询中,读者必须知道查询详细信息是否可以具有多个状态。因此,尽管我的查询看起来有点麻烦,但与仅联接查询相比,它仍然更清晰,因此更易于维护。

BTW:我已删除

and DTL.DetailId = CAD.DetailId

因为您的查询中没有表格CAD。

© www.soinside.com 2019 - 2024. All rights reserved.