MySQL с двумя таблицами INNER JOIN, LEFT JOINED на третью таблицу с одной строкой с наименьшим значением - PullRequest
0 голосов
/ 19 сентября 2018

Я искал вокруг и нашел возле примера к тому, что я ищу, но в моем случае это не сработало.

У меня есть запрос, который выполняет INNER JOINна двух таблицах, и это объединение существенно ограничивает мой общий набор данных.Затем я хочу присоединиться к третьей таблице , но мне нужна только одна запись из этой третьей таблицы .Причина левого соединения состоит в том, что не каждый результат INNER JOIN имеет совпадение в 3-й таблице.Примерно так:

SELECT DISTINCT t1.code, t2.id, t2.code, t3.id, t3.source_title, t3.display_order
FROM table1 t1
INNER JOIN table2 t2 ON t2.code=t1.code AND t2.type=0
LEFT JOIN table3 t3 ON t3.code=t1.code
ORDER BY t1.code, t3.display_order

Этот запрос возвращает слишком много записей, поскольку третья таблица содержит несколько записей с совпадающим кодом .Я просто хочу, чтобы первое совпадало с самым низким значением display_order , и, к сожалению, я не могу ограничить записи значением display_order = 1, потому что самый низкий порядок отображения не всегда один.

ВАЖНО : значение t3.id (если есть), возвращаемое этим запросом , должно соответствовать записи с наименьшим значением display_order. Т.е., если запрос будет работать некорректновозвращает наименьшее значение display_order, но значение t3.id соответствует какой-то другой записи в таблице 3.

Возможно ли это вообще?Любая помощь будет высоко ценится.

РЕДАКТИРОВАТЬ: В соответствии с предложением Ника, я попробовал это, который, кажется, работает.Я сделаю некоторые проверки и сообщу:

SELECT DISTINCT t1.code, t2.*, sq.id, sq.source_title, sq.display_order
FROM table1 t1
INNER JOIN table2 p ON t2.code=t1.code AND t2.type=0
LEFT JOIN (
    SELECT t3.*
    FROM table3 t3
    WHERE t3.display_order=(
        SELECT MIN(display_order)
        FROM table3 t3a 
        WHERE t3a.code = t3.code
    )
) sq ON sq.code=t1.code
ORDER BY t1.code, sq.display_order

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

В MySQL 8.0 вы можете попытаться использовать row_number() для каждого кода и упорядочить по display_order в подзапросе из table3.Затем присоединитесь к этому результату слева и проверьте, что row_number() равно 1.

SELECT DISTINCT
       t1.code,
       t2.id,
       t2.code,
       t3.id,
       t3.source_title,
       t3.display_order
       FROM table1 t1
            INNER JOIN table2 t2
                       ON t2.code = t1.code
            LEFT JOIN (SELECT t3.id,
                              t3.source_title,
                              t3.display_order,
                              t3.code,
                              row_number() OVER (PARTITION BY t3.code
                                                 ORDER BY t3.display_order) rn
                              FROM table3 t3) t3
                      ON t3.code = t1.code
       WHERE t2.type = 0
             AND t3.rn = 1
       ORDER BY t1.code,
                t3.display_order;

. В более низких версиях вы можете попробовать коррелированные подзапросы, упорядоченные по display_order и LIMIT 1 (чтобы получить только одну запись).

SELECT DISTINCT
       t1.code,
       t2.id,
       t2.code,
       (SELECT t3.id
               FROM table3 t3
               WHERE t3.code = t1.code
               ORDER BY t3.display_order,
                        t3.id
               LIMIT 1) id,
       (SELECT t3.source_title
               FROM table3 t3
               WHERE t3.code = t1.code
               ORDER BY t3.display_order,
                        t3.id
               LIMIT 1) source_title,
       (SELECT t3.display_order
               FROM table3 t3
               WHERE t3.code = t1.code
               ORDER BY t3.display_order,
                        t3.id
               LIMIT 1) display_order
       FROM table1 t1
            INNER JOIN table2 t2
                       ON t2.code = t1.code
       WHERE t2.type = 0
       ORDER BY t1.code,
                (SELECT t3.display_order
                        FROM table3 t3
                        WHERE t3.code = t1.code
                              ORDER BY t3.display_order,
                                       t3.id
                              LIMIT 1);

Я предположил, что display_order в table3 не уникален, а id есть.Поэтому я добавил id к предложениям ORDER BY в подзапросах, чтобы убедиться, что в каждом из них выбрана одна и та же запись.Если display_order уникален, вы можете удалить id ИЗ ORDER BY предложений.


Редактировать:

Если вы не хотите повторять подзапросы в (в целом) ORDER BY предложение, вы также можете заказать по порядку столбцов.Например:

...
ORDER BY 1, 6;
0 голосов
/ 19 сентября 2018

Вы должны иметь возможность заменить table3 в вашем LEFT JOIN на

(SELECT * 
 FROM table3 t3 
 WHERE display_order = (SELECT MIN(display_order) 
                        FROM table3 t3a 
                        WHERE t3a.code = t3.code)
) t3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...