Я часто выполняю пару независимых соединений со стола. Например, скажем, у нас есть таблица collections
, которая имеет независимые отношения «один к N» как с photos
, так и с songs
, где N - от нуля до многих.
Теперь, скажем, мы хотим получить коллекцию, и и (независимо) связанные с ней фотографии и песни.
Обычно я бы использовал что-то вроде этого:
SELECT
collections.collectionid as collectionid,
photos.name as photo_name,
songs.name as song_name
FROM collections
LEFT JOIN photos ON collections.collectionid = photos.collectionid
LEFT JOIN songs ON collections.collectionid = songs.collectionid
WHERE collections.collectionid = 14
Конечно, соединение левой таблицы с двумя другими таблицами, если первое соединение приводит к M
строкам, а второе к N
строкам, дает M * N
строк. Это может показаться неоптимальным с точки зрения трафика и производительности базы данных.
+--------------+------------+-----------+
| collectionid | photo_name | song_name |
+--------------+------------+-----------+
| 14 | 'x' | 'a' | \
| 14 | 'x' | 'b' | - Each photo is returned 3 times,
| 14 | 'x' | 'c' | / because 3 songs are returned.
| 14 | 'y' | 'a' | \
| 14 | 'y' | 'b' |
| 14 | 'y' | 'c' | /
+--------------+------------+-----------+
Кроме того, вы можете выполнить два выбора: два отдельных запроса, каждый из которых объединяет collections
в другую таблицу, давая M + N
строк:
SELECT
collections.collectionid as collectionid
song.name as song_name
FROM collections
LEFT JOIN songs on collections.collectionid = songs.collectionid
WHERE collections.collectionid = 14
и
SELECT
collections.collectionid as collectionid
photos.name as photo_name
FROM collections
LEFT JOIN photos on collections.collectionid = photos.collectionid
WHERE collections.collectionid = 14
дает:
+--------------+------------+ +--------------+------------+
| collectionid | song_name | | collectionid | photo_name |
+--------------+------------+ +--------------+------------+
| 14 | 'a' | | 14 | 'x' |
| 14 | 'b' | | 14 | 'y' |
| 14 | 'c' | +--------------+------------+
+--------------+------------+
Мой вопрос: как лучше всего с этим справиться?
Ничего из вышеперечисленного не кажется оптимальным. Итак, есть ли другой способ, который приводит к M + N
строкам, но может быть выполнен в одном запросе?