【问题标题】:How to retrieve products by tags (SQL question)如何按标签检索产品(SQL 问题)
【发布时间】:2011-05-25 01:34:23
【问题描述】:

我有两个 MySQL 表:

  • productidtitleprice 和其他一些产品属性
  • tag 有 *product_id* 和 *tag_name* 字段

每个 product 行可以在表 tag 中包含一个或多个行,由 *product_id* 字段连接。 问题:如何通过 *tag_name* 和其他属性选择产品? 示例:我需要选择所有价格低于 10 美元并带有“外国”和“科幻”标签的书籍

我知道如何选择带有一个标签的产品(通过 *product_id* 连接产品和标签并设置 where 子句) 我知道如何使用存储过程选择具有多个标签的产品,但是查询需要很长时间才能运行。 有没有办法避免存储过程仍然得到结果?

更新:当您单击右侧栏上的“相关标签”时,StackOverflow 会执行类似的操作。现在,我不知道他们的数据库有什么架构,但结果是相当快速地选择了所有带有多个标签的问题。

【问题讨论】:

    标签: sql mysql stored-procedures


    【解决方案1】:

    试试,

    SELECT p.* FROM products p 
    INNER JOIN tag t ON p.id = t.product_id 
    WHERE p.price < 10 AND p.id IN( SELECT product_id FROM tag  WHERE  t.tag_name = 'foreign' OR t.tag_name = 'sci-fi' GROUP BY product_id HAVING COUNT(product_id) = 2)
    

    【讨论】:

    • 这些都不起作用。他们都返回标记为“外国”或“科幻”的产品,我需要的是要求“外国”“科幻”标签都出现在所需产品的标签表中.
    • 好的,为此您只需将 (t.tag_name = 'foreign' OR t.tag_name = 'sci-fi') 替换为 t.tag_name = 'foreign' AND t.tag_name = '第一个查询中的科幻小说。忽略后面的两个查询。
    • 它现在什么都不返回(因为标签中的每一行只有一个标签名称,而不是两者)
    • 我已根据我对您的查询的理解进行了编辑,希望对您有所帮助。请立即检查。
    【解决方案2】:

    这将返回任何价格低于 10 且带有标签 foreignsci-fi

    的产品

    怎么样

    SELECT  p.*
    FROM    product p
    WHERE   p.price < 10
    AND     EXISTS  (
                        SELECT  1
                        FROM    tag t
                        WHERE   p.id = t.product_id
                        AND     t.tag_name IN ('foreign','sci-fi')
                    )
    

    这将确保它具有两个标签,假设标签具有主键 product_id 和 tag_name

    SELECT  p.*
    FROM    product p
    WHERE   p.price < 10
    AND     EXISTS  (
                        SELECT  1
                        FROM    tag t
                        WHERE   p.id = t.product_id
                        AND     t.tag_name IN ('foreign','sci-fi')
                        HAVING COUNT(1) = 2
                    )
    

    【讨论】:

    • tags 有一个主键,它完全是一个单独的字段 (id)。您的第二个查询是否还假设标签表中存在 product_id/tag_name 主键?
    • 您的第二个示例产生了所需的结果(即使我没有所需的主键)。我现在将对其进行分析,看看它是否比我的存储过程快
    • 第二个例子确实做到了,而且比我以前使用的存储过程快几倍。我没有主键,只有两个字段的常规索引。谢谢!附言我如何将我的问题标记为现在已回答? :)
    【解决方案3】:

    如果我的问题是正确的,这似乎是一个简单的查询。

    我看到的是:

    Select Product.* 
    from Product, Tag
    where Product.id = Tag.product_id
    and Product.price<$10
    and tag.tag_name in ('foreign', 'sci-fi')
    

    【讨论】:

    • 返回带有“外国”或“科幻”标签的产品。期望的结果是返回在标签表中具有两个标签名称的产品
    猜你喜欢
    • 2020-12-07
    • 1970-01-01
    • 2016-08-07
    • 1970-01-01
    • 2021-09-14
    • 1970-01-01
    • 2020-06-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多