Явный синтаксис соединения - PullRequest
0 голосов
/ 17 апреля 2020

Я улучшаю старое приложение, использующее запрос, подобный приведенному ниже. Я хотел бы преобразовать синтаксис, чтобы начать использовать явный синтаксис 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'
;

Ответы [ 2 ]

4 голосов
/ 17 апреля 2020

Попробуйте это:

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 голос
/ 17 апреля 2020

Вы показываете запрос с соединениями в стиле 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
);

Читатель этого запроса сразу увидит, что он не будет создавать дубликаты, что не относится к исходному запросу, где читатель должен знать, может ли деталь запроса иметь несколько статусов или нет. Таким образом, хотя мой запрос выглядит несколько затянувшимся, он все же более понятен и, следовательно, лучше обслуживается, чем запрос только для соединений.

Кстати: я удалил

and DTL.DetailId = CAD.DetailId

, потому что там нет таблицы CAD в вашем запросе.

...