我正在增强一个旧的应用程序,该应用程序使用与以下类似的查询。我想将语法转换为开始使用显式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'
;
尝试一下:
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';
您正在显示一个具有1980年代样式的联接的查询,并希望将它们更改为显式联接,这是一个好主意。但是联接并不是表示查询中关系的唯一方法。
在您的情况下,您正在从两个表中选择数据,但是涉及到第三个表。当header
中存在某个条目时,您只想从detail
和detailstatus
中选择数据。当我们要检查条目是否存在时,通常使用EXISTS
或IN
子句。这也将它所属的第三个表放在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。