Ответ 1
SELECT * FROM foo
LEFT OUTER JOIN (foo2bar JOIN bar ON (foo2bar.bid = bar.bid AND zid = 30))
USING (fid);
Протестировано в MySQL 5.0.51.
Это не подзапрос, он просто использует круглые скобки для указания приоритета соединений.
У меня есть 3 таблицы, foo, foo2bar и bar. foo2bar - это много-много карт между foo и bar. Вот содержание.
select * from foo
+------+
| fid |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
+------+
select * from foo2bar
+------+------+
| fid | bid |
+------+------+
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 2 | 3 |
| 4 | 4 |
+------+------+
select * from bar
+------+-------+------+
| bid | value | zid |
+------+-------+------+
| 1 | 2 | 10 |
| 2 | 4 | 20 |
| 3 | 8 | 30 |
| 4 | 42 | 30 |
+------+-------+------+
Я хочу запросить: "Дайте мне список всех fid и значений с zid 30"
Я ожидаю ответа для всех фидов, поэтому результат будет выглядеть так:
+------+--------+
| fid | value |
+------+--------+
| 1 | null |
| 2 | 8 |
| 3 | null |
| 4 | 42 |
+------+--------+
SELECT * FROM foo
LEFT OUTER JOIN (foo2bar JOIN bar ON (foo2bar.bid = bar.bid AND zid = 30))
USING (fid);
Протестировано в MySQL 5.0.51.
Это не подзапрос, он просто использует круглые скобки для указания приоритета соединений.
SELECT * FROM
foo LEFT JOIN
(
Foo2bar JOIN bar
ON foo2bar.bid = bar.bid AND zid = 30
)
ON foo.fid = foo2bar.fid;
непроверенных
Используя это, вы можете начать с вашего выбора. Не включайте столбцы, которые вы не хотите в конечном счете видеть.
SELECT foo.fid, bar.value
Затем мы можем сделать предложение WHERE, которое может видеть, так же, как вы его выразили.
SELECT foo.fid, bar.value
WHERE bar.zid = 30
Теперь сложная часть для соединения вещей для нашего предложения FROM, используя LEFT JOINs, потому что мы хотим видеть каждый фид, есть ли промежуточные совпадения:
SELECT foo.fid, bar.value
FROM foo
LEFT JOIN foo2bar ON foo.fid = foo2bar.fid
LEFT JOIN bar ON foo2bar.bid = bar.bid
WHERE bar.zid = 30
OR bar.zid IS NULL
Если вы не вернете строку для fid = 3, ваш сервер будет разорван.
Этот код должен делать то, что, я думаю, вам нужно:
SELECT
F.fid,
SQ.value
FROM
dbo.Foo F
LEFT OUTER JOIN
(
SELECT F2B.fid, B.value
FROM dbo.Bar B
INNER JOIN dbo.Foo2Bar F2B ON F2B.bid = B.bid WHERE B.zid = 30
) SQ ON SQ.fid = F.fid
Имейте в виду, что можно вернуть два значения для fid, если оно связано с двумя столбцами с zid 30.
FWIW, вопрос не в том, что касается многих-ко-многим: это может быть просто сделано как объединение.
Реальный много-много в SQL - это CROSS JOIN