我有这张桌子
----------------
| X | Y |
----------------
| a | 1 |
| c | 6 |
| e | 3 |
| d | 6 |
| c | 4 |
| b | 1 |
| a | 5 |
| g | 1 |
----------------
当我给出一个数组[c,d]时,我需要在上表中找到“6”。即对于每一组元素,我需要找到集合中所有元素共享的Y值,但前提是没有其他元素(即不在给定数组中的元素)共享该值。数组中的元素数量没有理论限制。
更多例子:对于[a,b,c],我不需要什么。对于[a,b]我也不需要找到任何东西(因为g也有一个Y = 1的条目,所以对于[a,b,g]我需要找到“1”)。
我当然可以遍历数组,按查询查询,但这似乎是一种低效的方式。在SQL中执行此操作的最佳方法是什么?谢谢。
答案 0 :(得分:2)
这些类型的查询从不特别适用于大型数据集和/或Y中的许多值在X中共享相同的值。
那就是说,这是我正常做法的简单版本......
CREATE TEMPORARY TABLE params (
item VARCHAR(16)
)
INSERT INTO params SELECT 'a'
INSERT INTO params SELECT 'b'
INSERT INTO params SELECT 'g'
SELECT
yourTable.Y
FROM
yourTable
LEFT JOIN
params
ON yourTable.X = params.item
GROUP BY
yourTable.Y
HAVING
COUNT(DISTINCT yourTable.X) = COUNT(DISTINCT params.item)
另一个不需要参数表的选项,虽然我不认为它更具性能......
SELECT
y
FROM
yourTable
GROUP BY
y
HAVING
COUNT(DISTINCT x) = COUNT(DISTINCT CASE WHEN x IN ('a', 'b', 'g') THEN x ELSE NULL END)
这没有连接,但是以进行全表扫描为代价。
答案 1 :(得分:2)
这是通过在单独的表中提供“查询”值的方法。
create table t ( x varchar(1), y int);
insert into t (x, y) values ('a', 1);
insert into t (x, y) values ('c', 6);
insert into t (x, y) values ('e', 3);
insert into t (x, y) values ('d', 6);
insert into t (x, y) values ('c', 4);
insert into t (x, y) values ('b', 1);
insert into t (x, y) values ('a', 5);
insert into t (x, y) values ('g', 1);
create table q ( x varchar(1) );
insert into q (x) values ('a');
insert into q (x) values ('b');
select a.y from
(
select t.y
from t join q on (t.x = q.x)
group by t.y
having count(*) = (select count(*) from q)
) a
join t on (a.y = t.y)
group by a.y
having count(*) = (select count(*) from q)
这假设你不能有重复的组合。
如果您想在没有第二个表的情况下执行此操作,可以将select count(*)
替换为您在IN列表中匹配的值的数量,而不是在内部子查询上进行连接,而是使用where子句。
select a.y from
(
select t.y
from t
where t.x in ('c', 'd')
group by t.y
having count(*) = 2
) a
join t on (a.y = t.y)
group by a.y
having count(*) = 2