Использование внутреннего соединения DISTINCT в SQL

У меня есть три таблицы, A, B, C, где A много к одному B, а B много к одному C. Мне нужен список всех C в A.

Мои таблицы выглядят примерно так: A [id, valueA, lookupB], B [id, valueB, lookupC], C [id, valueC]. Я написал запрос с двумя вложенными SELECT, но мне интересно, можно ли каким-то образом выполнить INNER JOIN с DISTINCT.

SELECT valueC
FROM C
INNER JOIN
(
    SELECT DISTINCT lookupC
    FROM B INNER JOIN
    (
        SELECT DISTINCT lookupB
        FROM A
    ) 
    A2 ON B.id = A2.lookupB
) 
B2 ON C.id = B2.lookupC

Обновлено: Таблицы довольно большие, A - 500 тыс. Строк, B - 10 тыс. Строк, а C - 100 строк, поэтому, если я сделаю базовое внутреннее соединение и использую DISTINCT в конце, будет много ненужной информации, например:

SELECT DISTINCT valueC
FROM 
C INNER JOIN B on C.id = B.lookupB
INNER JOIN A on B.id = A.lookupB

Это очень и очень медленно (по величине в разы медленнее, чем вложенный SELECT, который я сделал выше.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
37
0
354 643
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Это то, что вы имеете в виду?

SELECT DISTINCT C.valueC
FROM 
C
INNER JOIN B ON C.id = B.lookupC
INNER JOIN A ON B.id = A.lookupB

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

Mats Fredriksson 02.10.2008 12:58

Я изменил порядок соединения, который, в зависимости от того, какой SQL вы используете, может улучшить производительность запроса.

kristian 02.10.2008 13:12

Я считаю, что ваши отношения 1: м уже должны неявно создавать DISTINCT JOIN.

Но если ваша цель состоит только в C в каждом A, может быть проще просто использовать DISTINCT в самом внешнем запросе.

SELECT DISTINCT a.valueA, c.valueC
FROM C
    INNER JOIN B ON B.lookupC = C.id
    INNER JOIN A ON A.lookupB = B.id
ORDER BY a.valueA, c.valueC

Этого оказалось достаточно, проблема заключалась в том, что у меня не было индекса.

Mats Fredriksson 02.10.2008 18:37

SELECT DISTINCT C.valueC 
FROM C 
  LEFT JOIN B ON C.id = B.lookupC
  LEFT JOIN A ON B.id = A.lookupB
WHERE C.id IS NOT NULL

Я не вижу веской причины, по которой вы хотите ограничить наборы результатов A и B, потому что вы хотите иметь список всех C, на которые ссылается A. Я выделил C.valueC, потому что я догадался, что вы хотел уникальный список троек.


РЕДАКТИРОВАТЬ: Я согласен с вашим аргументом. Даже если ваше решение выглядит немного вложенным, оно кажется лучшим и самым быстрым способом использовать ваши знания данных и сократить наборы результатов.

Нет отдельной конструкции соединения, которую вы могли бы использовать, поэтому просто оставайтесь с тем, что у вас уже есть :)

Результат тот же, но вроде медленнее. Я не знаю точно, почему, но я предполагаю, что это потому, что он создает две огромные таблицы соединения с C.valueC будет очень большим. Поскольку я знаю, что B.lookupC должен быть ОТЛИЧИТЕЛЬНЫМ сам по себе, я хочу использовать эти знания, чтобы ускорить процесс.

Mats Fredriksson 02.10.2008 13:14
Ответ принят как подходящий

Я провел тест на MS SQL 2005, используя следующие таблицы: A 400K строк, B 26K строк и C 450 строк.

Предполагаемый план запроса показал, что базовое внутреннее соединение будет в 3 раза медленнее, чем вложенные подзапросы, однако при фактическом выполнении запроса базовое внутреннее соединение было в два раза быстрее, чем вложенные запросы. Базовое внутреннее соединение заняло 297 мс на очень высоком уровне. минимальное серверное оборудование.

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

Это была проблема с индексированием. Я использую MSSQL 2005 и наконец нашел помощника по настройке ядра СУБД. Я добавил индекс на A.lookupB, и это значительно ускорило работу. Спасибо за вашу помощь!

Mats Fredriksson 02.10.2008 18:30

Другие вопросы по теме