#mysql
Вопрос:
У меня есть таблица, в которой я храню некоторую информацию о заголовке. Каждая строка является резервированием, и есть поле, в котором я сохраняю, сколько гостей находится в этом резервировании (таблица: reservation_header)
ResId | гости |
---|---|
1 | 3 |
2 | 5 |
Затем у меня есть таблица, в которой я храню сведения о каждом госте (таблица: reservation_row)
ID | ResID | Имя | фамилия |
---|---|---|---|
1 | 1 | Джо | Смит |
2 | 1 | Фрэнк | Зеленый |
Теперь я хочу добиться следующего: для a reservation_header.ResId
присоединиться к таблице reservation_row столько раз, сколько значение guests (т.Е. 3 раза) и показать null, если гость не находится в reservation_row.
Если я сделаю
SELECT rh.ResId, rh.guests, rr.id,rr.name, rr.surname
FROM reservation_header rh LEFT JOIN reservation_row rr
WHERE rh.ResId=1
Я получаю только две записи, и я пропускаю третью с нулевыми именем и фамилией.
Ожидаемый результат:
ID | ResID | Имя | фамилия |
---|---|---|---|
1 | 1 | Джо | Смит |
2 | 1 | Фрэнк | Зеленый |
NULL | 1 | NULL | NULL |
Но я не могу получить третью строку. Очевидно, что количество строк в ожидаемом результате всегда будет равно reservation_header.guests
значению, поэтому для ResId 2 я буду искать 5 строк (все с нулевым значением с этими образцами данных)
Как я могу это получить?
Ответ №1:
Создайте вспомогательную таблицу с текущими числами для генерации дополнительных строк
with recursive counters as (
select 1 AS counts
union
select counts 1
from counters
where counts < ( select max(guests) from reservation_header)
),
guests as (
select *, row_number() over(partition by ResID order by id) as rn
from reservation_row
)
select r.id, rh.ResID, r.name, r.surname
from reservation_header rh
join counters c on rh.guests >= c.counts
left join guests r on rh.ResID = r.ResID and r.rn = c.counts
order by rh.resID
;
https://dbfiddle.uk/?rdbms=mysql_8.0amp;fiddle=b6cf01493438847fbe6c84f1913e1ef8
Комментарии:
1. это очень хороший подход. Спасибо, что поделились!
Ответ №2:
Когда вы добавляете значения в таблицу reservation_row , в это время вы должны вставлять строки в соответствии с количеством гостей. здесь вы должны были добавить 3 строки в таблицу reservation_row, 3-я строка с нулевыми значениями. тогда вы должны иметь возможность объединить две таблицы.
SELECT rh.ResId, rh.guests, rr.id,rr.name, rr.surname
FROM reservation_header rh RIGHT JOIN reservation_row rr
ON rh.ResId=rr.ResID AND rh.ResId=1