MySQL严格选择涉及多对多表的行
Posted
技术标签:
【中文标题】MySQL严格选择涉及多对多表的行【英文标题】:MySQL strict select of rows involving many to many tables 【发布时间】:2008-12-01 01:56:26 【问题描述】:我有三个多对多格式的表格。即,表 A、B 和 AB 已按您的预期设置。
给定一组 A id,我只需要选择 AB 中与所有 id 匹配的行。
以下内容不起作用:
"SELECT * FROM AB WHERE A_id = 1 AND A_id = 2 AND A_id = 3 AND ..." 因为没有一行会有多个 A_id
在 sql 语句中使用 OR 并没有更好的结果,因为它会产生至少具有一个 A id 的所有结果(而我只想要那些具有所有 id 的行)。
编辑:
对不起,我应该解释一下。我不知道实际的多对多关系是否与实际问题相关。表格概述如下:
Table People
int id
char name
Table Options
int id
char option
Table peoples_options
int id
int people_id
int option_id
所以我有一个人员列表,一个选项列表,以及一个选项和人员表。
所以,给定一个选项 ID 列表,例如 (1, 34, 44, ...),我只需要选择那些拥有所有选项的人。
【问题讨论】:
你能改写你的问题,也许添加一个模式的sn-p或什么?因为您似乎说 AB 中的每一行都有一个 A_id,然后您问如何提取与多个 A_id 匹配的 AB 行......这至少可以说是令人困惑。 您的问题似乎很荒谬。您的意思是您想要在给定的一组 A_ID 中具有对应 A 记录的所有 B 记录? 【参考方案1】:您的数据库似乎没有正确规范化。您的AB
表的每一行都应该有一个A_id
和一个B_id
。如果是这种情况,您的 OR
-version 应该可以工作(尽管我自己会使用 IN
)。
忽略前面的段落。从您的编辑中,您真的想知道在多对多表中具有 A
的所有子集的所有 B
- 查询见下文。
请告诉我们实际的架构详细信息,如果没有它,您将很难弄清楚您想要什么。
我希望看到类似的东西:
table a:
a_id integer
a_payload varchar(20)
table b:
b_id integer
b_payload varchar(20)
table ab:
a_id integer
b_id integer
根据您的描述,我唯一能想到的就是您想要在AB
表中拥有一组A
的所有B
的列表。在这种情况下,您正在查看类似的内容(以获取 B
的列表,其中 A
为 1、3 和 4):
select distinct b_id from ab n1
where exists (select b_id from ab where a_id = 1 and b_id = n1.b_id)
and exists (select b_id from ab where a_id = 3 and b_id = n1.b_id)
and exists (select b_id from ab where a_id = 4 and b_id = n1.b_id);
这在 DB2 中有效,但我不确定您选择的服务器实现了多少 SQL。
【讨论】:
我认为他的意思是他想要来自 AB 的所有 B_id 值,其中所有 A_id 值列表都存在。 抱歉,我觉得我的问题措辞不够好。【参考方案2】:一个 hacky 解决方案是将 IN 与 group by 一起使用并具有过滤器。像这样:
SELECT B_id FROM AB
WHERE A_id IN (1,2,3)
GROUP BY B_id
HAVING COUNT(DISTINCT A_id) = 3;
这样,您只能获得恰好具有 3 个 A_id 值的 B_id 值,并且它们必须来自您的列表。我在 COUNT 中使用了 DISTINCT,以防 (A_id, B_id) 不是唯一的。如果您需要其他列,则可以作为另一个 select 语句的 FROM 子句中的子选择加入此查询。
【讨论】:
【参考方案3】:试试这个....它带来了与所有选项相关联的所有人。
换句话说,该查询为所有人带来了它不存在与它无关的选项。
select
p.*
from
people p
where
not exists (
select
1
from
options o
where
not exists
(
select 1
from peoples_options po
where po.people_id = p.people_id
AND po.option_id = o.option_id
)
)
【讨论】:
以上是关于MySQL严格选择涉及多对多表的行的主要内容,如果未能解决你的问题,请参考以下文章