Выберите строки из таблицы, где строка в другой таблице с одинаковым идентификатором имеет определенное значение в другом столбце
В MySQL:
Если у нас есть две таблицы:
comments
key | value
=================
1 | foo
2 | bar
3 | foobar
4 | barfoo
и
meta
comment_key | value
=========================
1 | 1
2 | 1
3 | 2
4 | 1
Я хочу получить комментарии из таблицы comment
, у которой есть соответствующая comment_key
в таблице meta
, которая имеет конкретный value
(столбец value
в таблице meta
).
Например, я хотел бы выбрать все строки из таблицы comment
, которые имеют value
of 1
в таблице meta
:
Я ожидал бы следующих результатов:
key | value
=================
1 | foo
2 | bar
4 | barfoo
И если бы я должен был выбрать все строки из таблицы comment
, которые имеют value
of 2
в таблице meta
:
Я бы ожидал этого результата:
key | value
=================
3 | foobar
Я действительно надеюсь, что кто-то может помочь, спасибо всем вам заранее!
Думаю, мне нужно присоединиться? Любые указатели были бы замечательными, и, если это вообще возможно, короткое объяснение, чтобы я мог понять, где я ошибся, - поэтому я буду знать в следующий раз!
Ответы
Ответ 1
Я бы не рекомендовал JOIN для этого — или, вернее, я бы рекомендовал " semijoin", который является концепцией реляционной алгебры, не выраженной непосредственно в SQL. Семиоин - это, по сути, соединение, в котором вы хотите получать записи только из одной таблицы, но при условии, что они имеют соответствующие записи в другой таблице.
В нотации SQL эта концепция выражается косвенно, используя предложение IN
с подзапрос:
SELECT key, value
FROM comments
WHERE key IN
( SELECT comment_key
FROM meta
WHERE value = 1
)
;
(MySQL на самом деле закончит перевод, вернувшись в semijoin insideally — по существу это своего рода вырожденное внутреннее соединение &mdash, но предложение IN
- естественный способ выразить его в необработанном SQL.)
Ответ 2
Вы ищете простой, ванильный equi-join здесь.
SELECT `comment`.`key` AS `key`,
`comment`.`value` AS `value`
FROM `comments`
JOIN `meta`
ON `comments`.`key` = `meta`.`comment_key`
WHERE `meta`.`value` = 1;
Я не совсем уверен, какой совет вы ищете здесь, но вы можете больше узнать о теме (а не о MySQL) в Wikipedia SQL JOIN.
Я бы порекомендовал индексирование на comment
. key
и meta
. comment_key
, причем оба они были индексами PRIMARY KEY, предполагая, что вы хотите, чтобы там было только 1 meta
строка за comment
строка (PRIMARY КЛЮЧИ УНИКАЛЬНЫ по определению). Если вы хотите разрешить более 1 meta
за comment
, добавьте отдельный столбец id
в meta
и сделайте, чтобы PRIMARY KEY с comment_key
был только индексом b-дерева.
Я также не уверен, как производительность этого будет сравниваться с ответом "полусоединение", но для меня это более простой и естественный способ выражения запроса; хотя только с двумя таблицами, для MySQL не должно быть слишком сложно оптимизировать.
Ответ 3
Я бы использовал "INNER JOIN" следующим образом:
SELECT comments.key, comments.value FROM comments
INNER JOIN meta ON comments.key=meta.comment_key WHERE meta.value = 1;
Ура!; -)