我有一个 mysql 表,其中包含来自许多不同来源的结果,基本上是列:
id (PRIMARY KEY)
source (INT)
value (VARCHAR)
score (FLOAT)
例子
id source value score
-- ------ ----- -----
1 1 dog 0.2
2 1 cat 2.5
3 1 pig 4.0
4 2 dog 2.3
5 2 dog 1.5
6 2 cat 1.4
7 2 hen 0.7
我需要对sources执行 set 操作,例如1 ∩ 2 ∩ 3
or (1 + 2 + 3) ∩ (4 + 5 + 6)
(其中 + 表示联合),但使用该值作为键,并返回完整的行。我正在将表达式转换为选择语句(每个嵌套的子表达式都成为一个选择)。这些是网络上的请求,因此性能是一个问题,但另一方面,我将在初始请求后缓存结果。
让我们看看如何根据值查询两个源的交集中的行,1 ∩ 2
以示例为例。我可以用
SELECT value
FROM table
WHERE source=1 OR source=2
GROUP BY value HAVING COUNT (DISTINCT source) = 2
而且,我什至可以用
SELECT table.id, table.value, table.source
FROM (
SELECT value
FROM table
WHERE source=1 OR source=2
GROUP BY value HAVING COUNT (DISTINCT source) = 2) AS intersection
JOIN table ON intersection.value = table.value
WHERE table.source=1 or table.source=2
屈服
id source value score
-- ------ ----- -----
1 1 dog 0.2
2 1 cat 2.5
4 2 dog 2.3
5 2 dog 1.5
6 2 cat 1.4
但是,对于我需要处理的嵌套表达式,它不是一个易于使用的解决方案,因为它会返回到原始表并再次基于源进行限制。考虑寻找两个选择结果的交集,其中每个选择语句生成数据表的一个子集。我不能再加入全桌了。我必须加入两个选择的联合的交集,但这似乎根本无法扩展。
我认为的另一种方法是在 id 上使用 GROUP_CONCAT,然后将 id 列表拆分回行(在存储过程或 python 中)。该存储过程让我想到,也许我应该为整个查询编写自己的过程。
那么,是否有另一种方法可以使用 vanilla sql 进行这些查询?如果没有,我会尝试编写一个存储过程(以前从未做过,应该很有趣)。存储过程是最好的方法吗?关于使用第一个解决方案(临时表和连接)、第二个解决方案(group_concat 和 split)或完全使用第三个解决方案的任何建议?我对存储过程知之甚少,不知道我能得到多细的粒度。