В следующем от одного до многих
CREATE TABLE source(id int, name varchar(10), PRIMARY KEY(id));
CREATE TABLE params(id int, source int, value int);
где params.source - это внешний ключ к source.id
INSERT INTO source values(1, 'yes');
INSERT INTO source values(2, 'no');
INSERT INTO params VALUES(1,1,1);
INSERT INTO params VALUES(2,1,2);
INSERT INTO params VALUES(3,1,3);
INSERT INTO params VALUES(4,2,1);
INSERT INTO params VALUES(5,2,3);
INSERT INTO params VALUES(6,2,4);
Если у меня есть список значений параметров (скажем, [1,2,3]), как мне найти все источники, которые имеют ВСЕ значения в списке (источник 1, «да») в SQL?
Спасибо
Редактировать Изменен для обработки случая, когда может быть несколько вхождений значения для данного источника.
Попробуй это:
SELECT
*
FROM
source
WHERE
(
SELECT COUNT(DISTINCT value)
FROM params
WHERE params.source = source.id
AND params.value IN (1, 2, 3)
) = 3
Вы также можете переписать его в GROUP BY:
SELECT
source.*
FROM
source
INNER JOIN params ON params.source = source.id
WHERE
params.value IN (1, 2, 3)
GROUP BY
source.id,
source.name
HAVING
COUNT(DISTINCT params.value) = 3
Я бы определенно выбрал группу по синтаксису. Намного более выразительно и менее болезненно на вид.
что, если в params было несколько записей с одинаковым значением для одного и того же источника?
это хороший вопрос, Расс. Думаю, Джеймсу нужно сказать нам, правда это или нет.
Что ж, DISTINCT никогда не был моим первым решением чего-либо, и в его случае установка, которую я видел много раз, с одним и тем же значением более одного раза, является нетипичной. Но я соответствующим образом изменил решение.
Если вы знаете количество различных значений в таблице параметров, вы можете удалить params.values IN (1,2,3) в предложении WHERE выше и, возможно, использовать переменную int для сопоставления отдельного счетчика с
Я знаю, что этот вопрос действительно старый, но СПАСИБО за то, что вы поместили туда DISTINCT - разъяснили, как решить эту проблему с моей ситуацией, в которой повсюду были дубликаты.
SELECT s.*
FROM source AS s
JOIN params AS p ON (p.source = s.id)
WHERE p.value IN (1,2,3)
GROUP BY s.id
HAVING COUNT(DISTINCT p.value) = 3;
Вам нужен DISTINCT, потому что ваш params.value не может иметь дубликатов.
Это было самым элегантным, до того, как lassevk реализовал то же самое :)
Я надеюсь, что кто-то другой понимает это лучше, чем я ... возможно, вы захотите изменить его формулировку.