使用WHERE IN在SELECT中复制行

时间:2020-01-31 17:47:10

标签: sql postgresql join relational-division

我在建立一个查询时会遇到问题,该查询将使我获得唯一的行。情况是:

我有这样的TABLE产品:

id   name    price
==================
1    bolt    50
2    screw   4
3    hammer  40
4    drill   30

和TABLE这样的产品2标签:

id   id_product  id_tag
=======================
1    1           1
2    2           1
3    2           2
4    2           3
5    3           3

在我的应用中,我正在渲染包含所有产品的列表,并且正在构建一个过滤器,用户应可以选择零个或多个标签,并获得分配了指定标签的所有产品的列表(是在表products2tags中具有该产品ID和标签ID的行。

查询

SELECT *
FROM products AS p
   JOIN products2tags AS p2t
      ON p.id = p2t.id_product
   WHERE IN p2t.id_tag in (1, 3);
当我在过滤器中仅选择一个标签时

起作用(因此WHERE语句中只有一个标签ID。当我选择更多标签时,我仍然会得到结果,但是我多次获得了一些行-分配了多个标签。

我需要做的就是在选择多个标签时获得唯一的行。

编辑:

上表中查询的预期结果:

p.id   p.name   p.price   p2t.id   p2t.id_product   p2t.id_tag
==============================================================
1      bolt     50        1        1                1
2      screw    4         2        2                1         (only once)
4      drill    30        5        4                3

3 个答案:

答案 0 :(得分:1)

之所以发生这种情况,是因为您将标记包含在结果集中。试试

SELECT DISTINCT
    product.*
FROM products AS p
   JOIN products2tags AS p2t
      ON p.id = p2t.id_product
   WHERE IN p2t.id_tag in (3, 4);

答案 1 :(得分:0)

这将为您提供带有所选标签的产品ID:

SELECT p.id
FROM products AS p
   JOIN products2tags AS p2t
      ON p.id = p2t.id_product
   WHERE p2t.id_tag in (1, 3)
   group by p.id
   having count(*) = (select count(distinct id_tag) 
                      from products2tags where id_tag in (1, 3)
                     );

只需获取列表中具有标签ID之一的产品而无需重复:

SELECT distinct p.*
FROM products AS p
   JOIN products2tags AS p2t
      ON p.id = p2t.id_product
   WHERE p2t.id_tag in (1, 3);

答案 2 :(得分:0)

在p.id上使用distinct。

select distinct on (p.id) *
from products as p
   join products2tags as p2t
      on p.id = p2t.id_product
   where p2t.id_tag in (1, 3);