Левое объединение, возвращающее как больше, так и меньше строк после запроса - PullRequest
2 голосов
/ 04 апреля 2019

Я новичок в SQL, и я хотел бы попросить о помощи.У меня есть 2 таблицы, к которым я хочу присоединиться, и я хотел бы сгенерировать то же количество строк, что и в таблице 1.

Вот таблицы:

Таблица 1

+----------+------------+---------+-------+
| ENTRY_ID | ROUTE_NAME | STATION | BOUND |
+----------+------------+---------+-------+
|        1 |         1A |    ABCC |     1 |
|        2 |         2C |    CBDD |     1 |
|        3 |          5 |    AAAA |     2 |
|        4 |         1A |    EEEE |     1 |
|        5 |         2B |    ASFA |     2 |
|        6 |          5 |    DSAS |     1 |
|        7 |          3 |    QWEA |     2 |
|        8 |          4 |    ASDA |     1 |
+----------+------------+---------+-------+

Таблица 2

+------------+-------+---------+---------------+
| ROUTE_NAME | BOUND | STATION | STOP_SEQUENCE |
+------------+-------+---------+---------------+
|         1A |     1 |     AAA |             1 |  
|         1A |     1 |     ABC |             2 |
|         1A |     1 |     CDA |             3 |
|         1A |     2 |     ABC |             1 |
|         1A |     2 |     ADC |             2 |
|         1A |     2 |     ACA |             3 |

Повторяется для других маршрутов

Краткое описание таблицы: Table 1 содержит определенные транзитные поездки, при этом транзитный маршрут принимается за ROUTE_NAME, отправлениеостановка как STATION и транзитная привязка как BOUND (только 1/2).Table 2 содержит набор данных о транзитном маршруте с полем, аналогичным таблице 1, и последовательностью остановки, такой как STOP_SEQUENCE

. Я хотел бы использовать STATION, BOUND иROUTE_NAME IN В таблице 1 для вызова STOP_SEQUENCE в таблице 2. Я использовал код:

SELECT t1.ENTRY_ID, t1.ROUTE_NAME, t1.STATION, t1.BOUND, t2.STOP_SEQUENCE
FROM T1 
LEFT JOIN t2 ON 
(t1.STATION LIKE '*' & t2.STATION & '*') AND
(t1.BOUND = t2.BOUND) AND
(t1.ROUTE_NAME = t2.ROUTE_NAME);

LIKE является обязательным, поскольку существует некоторое несоответствие между строкой STATION в 2таблицы, которые могут обрабатываться функцией.

Вопрос first состоит в том, почему LEFT JOIN не возвращает все строки из TABLE 1?У меня есть похожий код, который работает в других подобных таблицах.Для данных, которые не совпадают (с оператором LIKE), NULL возвращается для этой конкретной строки.Однако в этом запросе возвращается меньше строк.

Вопрос second заключается в том, что с помощью оператора LIKE я возвращаю одну или несколько строк из таблицы 2 из таблицы 1, что соответствует моим критериям (чтов моем коде произошло, что было возвращено 2+ строки с одинаковыми ENTRY_ID).Как я могу сохранить минимум возвращаемого ряда?т.е. если найдены два STOP_SEQUENCE, верните нижний.

Долго боролись за это, так что большое спасибо за вашу помощь!

ОБНОВЛЕНИЕ У меня естьУстановлено, что предложение t1.STATION LIKE '*' & t2.STATION & '*' вызывает отсутствие строк, как в первом вопросе.Я заменил его на =, и все строки снова появились.Однако мне все еще нужно это предложение LIKE, что я могу сделать?

1 Ответ

0 голосов
/ 04 апреля 2019

Почему LEFT JOIN не возвращает все строки из таблицы 1?

Я мог только подозревать, что это проблема вашего тестирования, поскольку код SQL, отправленный в вашем вопросе, вернет значения, содержащиеся в столбцах t1.ENTRY_ID, t1.ROUTE_NAME, t1.STATION, & t1.BOUND для всех записей в вашем table t1 и значение t2.STOP_SEQUENCE для всех записей в вашей таблице t2, которые удовлетворяют критериям объединения для каждой записи в вашей таблице t1.

Обратите внимание, что при этом будет возвращено несколько записей из таблицы t2, если более одной записи удовлетворяет критериям объединения для данной записи в таблице t1. Что приводит к следующему вопросу:

С помощью оператора LIKE я возвращаю одну или несколько строк из таблицы 2 из таблицы 1, что соответствует моим критериям (в моем коде произошло, что было возвращено 2+ строки с одинаковым ENTRY_ID). Как я могу сохранить минимум возвращаемого ряда? то есть, если найдено два STOP_SEQUENCE, вернуть нижний.

Этого можно добиться с помощью простого агрегирования с помощью функции min:

select
    t1.entry_id,
    t1.route_name,
    t1.station, 
    t1.bound,
    min(t2.stop_sequence) as stopseq
from
    t1 left join t2 on
    t1.station like '*' & t2.station & '*' and
    t1.bound = t2.route_bound and
    t1.route_name = t2.route_name
group by
    t1.entry_id,
    t1.route_name,
    t1.station, 
    t1.bound

Это вернет минимальное значение, сохраняемое полем t2.stop_sequence в группе, определенной каждой комбинацией значений, удерживаемых t1.entry_id, t1.route_name, t1.station, & t1.bound.


Кроме того, обратите внимание, что образец таблицы t2 в вашем вопросе не содержит поле route_bound, на которое ссылается ваш опубликованный код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...