SQL два join в одной и той же таблице?

Ссылка скопирована
1 ответ

Здравствуйте, есть таблица items:

item_id uniqueidentifier not null constraint pk_items primary key, firstDocument uniqueidentifier not null, lastDocument uniqueidentifier not null

item_id uniqueidentifier not null constraint pk_items primary key, firstDocument uniqueidentifier not null, lastDocument uniqueidentifier not null

Есть таблица documents

docid uniqueidentifier not null constraint pk_docs primary key, op_type int not null

docid uniqueidentifier not null constraint pk_docs primary key, op_type int not null

Надо вернуть коды операций для первого и последнего документов.
Кроме как использовать join дважды, получается выхода нет. Я правильно понимаю, что это реально будет в 2 раза медленнее происходить?

select      i.item_id,      i.firstDocument,      fd.op_type,      i.lastDocument,     ld.op_type from      items i left join documents fd on fd.docid = i.firstDocument left join documents ld on ld.docid = i.lastDocument

select i.item_id, i.firstDocument, fd.op_type, i.lastDocument, ld.op_type from items i left join documents fd on fd.docid = i.firstDocument left join documents ld on ld.docid = i.lastDocument

Дополнительно:

Надо вернуть коды операций для первого и последнего документов.

Сначала надо получить сами документы. Тут два варианта - либо два ROW_NUMBER() в CTE и отбор во внешнем запросе, либо два FIRST_VALUE() и DISTINCT.

И только потом связываться с таблицей кодов операций. Тут тоже два варианта - либо связывать с двумя копиями таблицы, либо связывать с одной по OR и агрегировать.

Что быстрее - ну это надо смотреть планы. Может, даже подумать о создании подходящего индекса, если его нет.

Я правильно понимаю, что это реально будет в 2 раза медленнее происходить?

При наличии оптимальных индексов - нет, неправильно. Да и вообще неправильно. Программисты не идиоты. Да, сканировать таблицу или индекс придётся дважды - но читать с диска-то можно и один раз...

SELECT items.item_id AS Item, FirstDoc.op_type AS FirstDocOper, LastDoc.op_type AS LastDocOper   FROM items      INNER JOIN documents AS FirstDoc ON items.firstDocument = FirstDoc.docid      INNER JOIN documents AS LastDoc ON items.lastDocument = LastDoc.docid

SELECT items.item_id AS Item, FirstDoc.op_type AS FirstDocOper, LastDoc.op_type AS LastDocOper FROM items INNER JOIN documents AS FirstDoc ON items.firstDocument = FirstDoc.docid INNER JOIN documents AS LastDoc ON items.lastDocument = LastDoc.docid

Ответы:

Я правильно понимаю, что это реально будет в 2 раза медленнее происходить?

Естественно.
Но по docid у вас индекс, так что должно быть достаточно быстро.

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Павел Админов Ответ

Для выполнения двойного join на одной и той же таблице в SQL, вы можете использовать псевдонимы для таблиц. Псевдонимы позволяют ссылаться на одну и ту же таблицу несколько раз в одном запросе. Вот пример запроса с двумя join на одну и ту же таблицу:

SELECT e.employee_id, e.employee_name, m.manager_name
FROM employees e
JOIN managers m ON e.manager_id = m.manager_id
JOIN employees e2 ON m.employee_id = e2.employee_id

SELECT e.employee_id, e.employee_name, m.manager_name FROM employees e JOIN managers m ON e.manager_id = m.manager_id JOIN employees e2 ON m.employee_id = e2.employee_id

В этом запросе используются два join на таблицу "employees". Первый join связывает сотрудников с их менеджерами, а второй join связывает менеджеров с их сотрудниками. Псевдонимы "e" и "m" используются для обозначения таблиц "employees" и "managers" соответственно.

Таким образом, вы можете использовать псевдонимы для таблиц и выполнять двойные join на одной и той же таблице в SQL. Не забывайте указывать условия соединения для каждого join, чтобы корректно связать данные из таблицы.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно