SQL多对多,如何检查多行的条件

Posted

技术标签:

【中文标题】SQL多对多,如何检查多行的条件【英文标题】:SQL many-to-many, how to check criteria on multiple rows 【发布时间】:2018-05-21 16:29:20 【问题描述】:

在多对多表中,如何找到所有条件都匹配的ID,但可能一行匹配一个条件,另一行匹配另一个条件?

例如,假设我有一个将购物车映射到产品的表,以及定义产品的另一个表。

我怎样才能找到一个购物车至少有一个匹配每个条件?

条件可以是,例如,product.category like '%fruit%'product.category like '%vegetable%' 等。

最终我想取回一个shopping cart ID(可能是所有这些,但在我的具体情况下,我很高兴获得任何匹配的 ID),其中至少包含每个匹配项。

【问题讨论】:

您能否提供一个有关您的架构、您的数据以及您想要返回的内容的示例? 【参考方案1】:

我假设有一个名为 cart_per_product 的表,其中包含字段 cart、product,以及一个名为 product 的表,其中包含字段 product、category。

select cart from cart_per_product c
where exists 
(
    select 1 from product p1 where p1.product=c.product and p1.category like N'%fruit%'
)
and exists 
(
    select 1 from product p2 where p2.product=c.product and p2.category like N'%vegetable%'
)

【讨论】:

【参考方案2】:

您可以将ANY 和ALL 运算符与外连接结合使用。在 M:N 关系上的 simple sample:

select p.name
  from products p
 where id_product = ALL    -- all operator 
 (  select pc.id_product
     from categories c 
     left outer join product_category pc on pc.id_product = p.id_product and
                                          pc.id_category = c.id_category
 )

【讨论】:

【参考方案3】:

我想你可以弄清楚列名

select c.id 
from cart c
join product p 
  on c.pID = p.ID 
group by c.id 
having count(distinct p.catID) = (select count(distinct p.catID) from product)

【讨论】:

【参考方案4】:

可能不是最有效的通用方法:

with data as (
    select *,
        count(case when <match condition> then 1 end)
            over (partition by cartid) as matches
    from <cart inner join products ...>
)
select * from data
where matches > 0;

【讨论】:

以上是关于SQL多对多,如何检查多行的条件的主要内容,如果未能解决你的问题,请参考以下文章

触发器根据多对多关系插入多行

检查多对多关系或属性

如何编写通过关系表获取结果的 SQL 语句? (多对多)

如何编写多对多的sql脚本

如何在 Hibernate 的条件中使用多对多关联中的索引列?

如何使用AND条件选择多对多关系中的记录[重复]