【问题标题】:Select rows whose mappings are a subset of given input in a many-to-many mappings table在多对多映射表中选择其映射是给定输入子集的行
【发布时间】:2015-01-12 07:15:00
【问题描述】:

我有一个包含产品和标签列的多对多表。如何查询“给我在其映射中只有这些标签之一的产品列表”?

Input : '2,3,4' (这对应于 Mappings 表中的 tagid 列)

预期输出:3,4,5(这对应于 productid 列。产品 3,4,5 的标签是 '2,3,4' 的子集(或真子集))。

-- Table: Product
+---------+-----------+
| productid | name      |
+---------+-----------+
|       1 | HTC       |
|       2 | Nokia     |
|       3 | Samsung   |
|       4 | Motorolla |
|       5 | Apple     |
+---------+-----------+

-- Table: Mappings
+------+-----------+
| tagid| productid |
+------+-----------+
|    1 |       1   |
|    1 |       2   |
|    2 |       1   |
|    2 |       3   |
|    3 |       1   |
|    3 |       4   |
|    4 |       5   |
+------+-----------+

-- Table: Tags
+------+-------+
| tagid  | name  |
+------+-------+
|    1 | blue   |
|    2 | black  |
|    3 | pink   |
|    4 | gold   |
+------+-------+

编辑:

预期输出说明: 输入 tagIds - {2,3,4} 。 对于 tagId 2,我们在映射表中映射了 productIds { 1,3 }。 tagId 3 有一个映射 {1, 4},而 tagId 4 有一个映射 {5}。所以 productIds 的组合列表是 {1,3,4,5}。
但是现在 productId 1 有一个与之关联的 tagId 1 ,它不在 tagIds 的输入列表中。所以最终的输出应该是 {3, 4 , 5}。希望这可以解决问题。

【问题讨论】:

  • 所以您希望所有产品都在您的输入标签中包含所有映射?就这么简单?
  • 在我的回答中添加了解决方案

标签: mysql sql


【解决方案1】:

这行得通吗?它适用于 MS-SQL。我目前没有运行 mysql 数据库实例。

select * from products
where (select count(*) from mappings 
       where products.productid=mappings.productid
       AND mappings.tagid in (2,3,4)) = 1

如果您添加 GROUP BY 子句,@Florian 的解决方案也将起作用:

SELECT products.productid,products.productname,count(*)
FROM products
INNER JOIN mappings on products.productid = mappings.productid
AND mappings.tagid in (2,3,4)
GROUP BY products.productid,products.productname
HAVING count(*)=1

【讨论】:

  • 谢谢我添加了它。很确定您不需要结果字段列表中的聚合函数。
  • 酷。我正在研究我对 MS SQL 的了解,如果 select 子句中的任何内容既不是聚合函数也不是 GROUP BY 子句,那么任何聚合子句都会阻塞。感谢您提供信息。
  • @Florian,对不起,误读了。不,根本不需要聚合函数。另外,我错过了 tagid 过滤器。
【解决方案2】:

类似的东西?:

select products.productid, products.name
from products inner join mappings on products.productid = mappings.productid
where mappings.tagid in (2,3,4) -- 2,3,4 is your input
group by products.productid , products.name
having count(*) = 1

编辑:

select products.productid, product.name
from products
where not exists 
(
    select * from mappings
    where products.productid = mappings.productid and not mappings.tagid in (2,3,4)
)

【讨论】:

    猜你喜欢
    • 2020-11-23
    • 1970-01-01
    • 2023-03-14
    • 2012-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 1970-01-01
    相关资源
    最近更新 更多