SQL два join в одной и той же таблице?
Здравствуйте, есть таблица 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 у вас индекс, так что должно быть достаточно быстро.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для выполнения двойного 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
В этом запросе используются два join на таблицу "employees". Первый join связывает сотрудников с их менеджерами, а второй join связывает менеджеров с их сотрудниками. Псевдонимы "e" и "m" используются для обозначения таблиц "employees" и "managers" соответственно.
Таким образом, вы можете использовать псевдонимы для таблиц и выполнять двойные join на одной и той же таблице в SQL. Не забывайте указывать условия соединения для каждого join, чтобы корректно связать данные из таблицы.