我在 mysql 中有这样的方案:
TableA (id整数PK, pid 整数, mid 整数)
实施例。数据:
id | pid | mid
1 | 2 | 2
2 | 2 | 4
3 | 3 | 4
4 | 4 | 2
5 | 4 | 4
6 | 3 | 2
7 | 3 | 5
我有 pid 和一些 mid ,并希望找到所有 pid 的 mid < / EM>的。 pid=2
答案为2,4
group_concat不适合我
我认为它应该很简单,但答案是我不知道的
UPD :
我试过了group_concat
:
SELECT DISTINCT(b.pid) FROM (SELECT pid, group_concat(mid) as concated FROM TableA where pid=100293) as a, (select pid, group_concat(mid) as concated, COUNT(1) as count FROM TableA group by pid) as b where a.concated=b.concated;
答案 0 :(得分:1)
由于您使用的是整数,而不是group_concat
,因此您可以为每个mid
生成不同pid
值的位掩码并加入其中。然后它只是数学一直下来:
SELECT DISTINCT pid
FROM (SELECT pid, sum(pow(2,mid)) as midmask FROM (SELECT distinct pid, mid FROM tableA) as t1a GROUP BY pid) as t1
INNER JOIN (SELECT pid, sum(pow(2,mid)) as midmask FROM (SELECT distinct pid, mid FROM tableA) as t2a GROUP BY pid) as t2
ON t1.midmask = t2.midmask
如果每个mid
pid
已经不同,那么你就可以摆脱内在的子查询。
使用@ GordonLinoff优秀的单子查询方法,其中GROUP_CONCAT仅用于主查询(它不会那么昂贵)。我们使用可能更快的位掩码方法而不是内部查询中的group_concat。
SELECT midmask>>1, group_concat(pid)
FROM (SELECT pid, sum(pow(2,mid)) as midmask FROM (SELECT distinct pid, mid FROM tableA) as t1a GROUP BY pid) as t1
GROUP BY midmask;
结果:
+---------+-------------------+
| midmask | group_concat(pid) |
+---------+-------------------+
| 10 | 2,4 |
| 26 | 3 |
+---------+-------------------+
显然,结果集中的中间掩码不是非常必要,但是如果你想看到有助于匹配的mid
值,你可以从位掩码中选择值。
我正在使用位右移运算符来确保在中间掩码结果中设置了正确的位,否则您将被关闭。如果您不关心中间掩码的输出,那么请不要打扰查询的>>1
部分。
答案 1 :(得分:0)
您可以使用此查询。它会给你逗号分隔的pids。
select `mid`, group_concat(`pid`) from `tableA` group by `mid`;
答案 2 :(得分:0)
在MySQL中,我会使用group_concat()
:
select mids, group_concat(pid)
from (select pid, group_concat(mid order by mid) as mids
from t
group by pid
) t
group by mids;
这解决了所有pids的一般问题。解决1 pid在MySQL中有点棘手(没有窗口函数),但你可以尝试:
select t.pid, t2.pid, count(*)
from t join
t t2
on t.mid = t2.mid and t2.pid = 2
group by t.pid, t2.pid
having count(*) = (select count(*) from t where t.pid = t.pid) and
count(*) = (select count(*) from t where t.pid = t2.pid);
为此,您需要t(mid, pid)
和t(pid)
上的索引。