【问题标题】:Query for product count with matching tags per tag查询每个标签匹配标签的产品计数
【发布时间】:2022-01-09 07:06:54
【问题描述】:

我有一个产品表,每个产品可以有多个标签,产品可以通过这些标签过滤。

我正在尝试获取基于活动过滤器的标签列表。

产品

+----+-----------+
| id |   name    |
+----+-----------+
|  1 | Product 1 |
|  2 | Product 2 |
|  3 | Product 3 |
+----+-----------+

标签

+----+-----------+
| id |   name    |
+----+-----------+
|  1 | Tag1      |
|  2 | Tag 2     |
|  3 | Tag 3     |
+----+-----------+

产品标签

+-----------+-------+
| productId | tagId |
+-----------+-------+
|         1 |     1 |
|         1 |     2 |
|         1 |     3 |
|         2 |     1 |
|         2 |     2 |
|         3 |     1 |
+-----------+-------+

我想得到的标签结果表如下所示:

id name productCount
1 Tag1 3
2 Tag2 0
3 Tag3 1

【问题讨论】:

  • 根据问题指南,请展示您的尝试并告诉我们您发现了什么(在本网站或其他地方)以及为什么它不能满足您的需求。
  • @JoelCoehoorn 这只是一个例子......想象一下有活动的标签过滤器......就像 Tag1 被过滤但没有带有 Tag1 和 Tag2 的产品。但是有一个带有 Tag1 和 Tag3 的产品和 3 个带有 Tag1 的产品
  • @DaleK 我发布了我想出的答案,但并没有真正找到完整的答案,只是部分答案。
  • 我发布了答案,以防有人会发现它有帮助,并查看是否有更好的解决方案。

标签: sql sql-server tsql


【解决方案1】:

所以我想出了这个似乎工作正常的查询。

它根据标签过滤器获取标签。 如果产品按标签 1 和标签 2 过滤,我会得到所有标签,如果按每个标签过滤,我会得到剩余产品的数量。

SELECT
t.id,
t.name,
(
    SELECT COUNT(*) from (
        SELECT
        pt.productId
        FROM productTags pt

        INNER JOIN productTags pt2
            ON pt2.productId = pt.productId
            AND pt2.tagId IN (1,2)

        WHERE pt.tagId = t.id

        GROUP BY pt.productId

        HAVING COUNT(DISTINCT pt2.tagId) = 2

    ) AS count

) AS count

FROM tags t

【讨论】:

  • 不要在你的回答中提出问题...在你的问题中提出。
【解决方案2】:

试试这个:

SELECT t.id, t.Name, COUNT(DISTINCT pt.productId) as productCount
FROM Tags t
LEFT JOIN ProductTags pt on pt.tagId = t.id
GROUP BY t.id, t.Name

或者使用过滤器:

SELECT t.id, t.Name, COUNT(DISTINCT pt.productId) as productCount
FROM Tags t
LEFT JOIN ProductTags pt on pt.tagId = t.id
WHERE t.id IN (1,2)
GROUP BY t.id, t.Name

或使用过滤器,但仍显示所有标签:

SELECT t.id, t.Name, COALESCE(pc.productCount,0) as productCount
FROM Tags t
LEFT JOIN (
    SELECT pt.tagId, COUNT(DISTINCT pt.productId) as productCount
    FROM ProductTags pt 
    WHERE pt.tagId IN (1,2)
    GROUP BY pt.tagId
) pc ON t.id = pc.tagId

【讨论】:

  • 谢谢!我尝试了所有这些,但它们在我的用例中并没有真正起作用..我需要与我的答案中的查询相同的结果
【解决方案3】:

你可以使用这个查询

SET ANSI_WARNINGS OFF;


CREATE TABLE tag (
    id int identity(1,1),
    tagname varchar(100),
  

)


    CREATE TABLE product (
    id int identity(1,1),
    productName varchar(100),
  

)

CREATE TABLE pt (
    pid int null,
    tid int null,
  

)

       insert product
       values('A')
       
       insert product
       values('B')
    
       insert tag
       values('Aa')
                   
       insert tag
       values('Bb')

insert pt
       values(1,1)
insert pt
       values(1,1)

select tag.tagname,
count(pt.pid)productcount
from tag
left join
pt on pt.tid=tag.id
group by 
tag.tagname

所以结果是:

如果在 SET ANSI_WARNINGS OFF 后有错误; 使用围棋

对于将行显示为 id,您可以使用此查询

select 
 ROW_NUMBER() OVER(ORDER BY tag.tagname) AS id  
,
tag.tagname,
count(pt.pid)productcount

from tag
left join
pt on pt.tid=tag.id
group by 
tag.tagname

所以结果是

【讨论】:

  • 谢谢!当我有时间的时候我会试试的。这也适用于活动标签过滤器吗?如果假设 Tag Aa 已经是一个活动过滤器?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多