#sql #sql-server-2016
#sql #sql-server-2016
Вопрос:
У меня есть этот запрос. Существует множество соединений, потому что я проверяю, связан ли идентификатор с какой-либо из этих таблиц.
В настоящее время этот запрос показывает мне любые идентификаторы, которые не связаны ни с одной из этих таблиц. Я хотел бы добавить к нему, чтобы он также отображал любые идентификаторы, которые связаны с общей таблицей, но только если в общей таблице всего 1 строка, а тип в общем поле — ‘member’.
SELECT
c.ID,
c.location,
c.pb,
c.name,
c.surname
FROM c
LEFT JOIN l on c.rowno = l.rowno
LEFT JOIN d on c.rowno = d.rowno
LEFT JOIN t on c.rowno = t.rowno
LEFT JOIN cj ON (c.rowno = cj.rowno OR c.rowno = cj.rowno2)
LEFT JOIN dj ON c.rowno = d.rowno
LEFT JOIN lg ON c.rowno = lg.rowno
LEFT JOIN tj ON c.rowno = tj.rowno
WHERE
c.status != 'closed'
AND l.rowno IS NULL
AND d.rowno IS NULL
AND t.rowno IS NULL
AND cj.rowno IS NULL
AND dj.rowno IS NULL
AND lg.rowno IS NULL
AND tj.rowno IS NULL
Моя первая мысль — просто добавить
WHERE D.type = 'member'
Но это дает мне все идентификаторы, в которых есть строка с D.type = member (у них может быть 10 строк с разными типами, но пока 1 из них имеет type = member, он отображается). Я хочу видеть идентификаторы, которые имеют только d.type = member
Извините, если я плохо формулирую, у меня возникли проблемы с тем, чтобы разобраться с этим в моей голове. Любая помощь приветствуется!
Комментарии:
1. Посмотрите, что произойдет, если вместо этого вы введете это условие в предложение ON.
2. вы заявляете / подразумеваете, что ваш запрос показывает таблицы со связанными строками на основе ID, но все ваши соединения основаны на другом поле (rowno), поэтому ваш запрос показывает связи на основе rowno. что такое rowno?
3. rowno — это PK, хотя идентификатор также является уникальным полем. для нашей базы данных rowno — это очень длинное число, поэтому у нас есть ID как более удобный для чтения идентификатор (я его не создавал)
Ответ №1:
Я бы использовал exists
для всех условий, кроме того, что указано в D
таблице:
SELECT c.*
FROM c JOIN
(SELECT d.rownum, COUNT(*) as cnt,
SUM(CASE WHEN d.type = 'Member' THEN 1 ELSE 0 END) as num_members
FROM t
GROUP BY d.rownum
) d
ON c.rownum = d.rownum
WHERE c.status <> 'closed' AND
NOT EXISTS (SELECT 1 FROM t WHERE c.rowno = t.rowno) AND
NOT EXISTS (SELECT 1 FROM l WHERE c.rowno = l.rowno) AND
. . .
Я считаю, NOT EXISTS
что логически следовать проще. Я не думаю, что существует большая разница в производительности между двумя методами в SQL Server.
Комментарии:
1. производительность определенно становится проблемой с этим конкретным запросом — я обнаружил, что привязка ко многим таблицам немного замедляет работу. Я попробую этот способ, спасибо!