【问题标题】:MySQL struggling with query in one to many relationship matching multiple conditionsMySQL在匹配多个条件的一对多关系中苦苦挣扎
【发布时间】:2010-12-01 16:30:57
【问题描述】:

我有两张表,大致如下:

products            product_attributes
==================  ========================================
| id | name      |  | id | product_id | attribute | value  |
==================  ========================================
| 1  | product 1 |  | 1  | 1          | size      | big    |
| 2  | product 2 |  | 2  | 1          | colour    | red    |
| 3  | product 3 |  | 3  | 2          | size      | medium |
| 3  | product 3 |  | 4  | 2          | age_range | 3-5    |
| .. | ...       |  | 5  | 2          | colour    | blue   |
==================  | 6  | 3          | size      | small  |
                    | .. | ...        | ...       | ...    |
                    ========================================

一个产品可能有无限数量的属性,这就是为什么它们被保存在一个单独的表中。

我希望能够提取与多个(也是无限)属性条件匹配的不同产品,但我想不出如何在不使用 OR 条件的情况下执行此操作,然后使用某种计数来检查所有属性是否匹配.我很确定这不是最好的方法,所以希望有人能提供帮助?!

例如,查找 size = 'medium' 和 color = 'blue' 的产品(这将匹配上例中的产品 2)。

【问题讨论】:

    标签: mysql one-to-many


    【解决方案1】:

    这是relational division 问题。

    COUNT 建议的方式可能是 MySQL 中最简单的方式

    SELECT product_id
    FROM product_attributes pa
    WHERE (attribute='size' and value='medium')
    OR (attribute='colour' and value='blue')
    GROUP BY product_id
    HAVING COUNT(DISTINCT CONCAT(attribute,value) ) = 2
    

    在链接的文章中还有另一种使用双 NOT EXISTS 的方法,但由于 MySQL 不支持 CTE,这会很麻烦。

    【讨论】:

    • 谢谢,这有点符合我的想法,但我希望可能有更有效的方法。我知道这不太可能,但如果我的属性“siz”和“size”分别具有“esmall”和“small”的值,我认为 DISTINCT CONCAT(attribute, value) 可能会遇到问题是否正确?我知道这不太可能,但我要处理大量的第 3 方数据,所以有没有办法使用属性 ID 或诸如 DICTINCT(pa.id) 之类的东西来保证唯一的组合?
    • @atkaye - 是的,这会给你带来麻烦。我最初使用COUNT(*),但对其进行了编辑。您对列组合product_id,attribute 是否有唯一约束?即,特定产品的任何特定属性是否只能具有一个值?
    • 是的,一个属性只能有一个值。您删除 COUNT(*) 是否有原因?
    • @atkaye - 因为我不确定是否存在任何此类限制。如果有,那么count(*) 可以正常工作。
    【解决方案2】:

    我认为这应该可以解决问题:

    SELECT a.product_id, p.name FROM product_attributes AS a LEFT JOIN products p ON (a.product_id=p.id) WHERE (a.attribute="size" AND a.value="medium") OR (a.attribute="colour" AND a.value="blue") GROUP BY a.product_id
    

    【讨论】:

    • 谢谢,我想和上面的答案一样,但只是缺少计数以确保所有条件都匹配
    猜你喜欢
    • 2011-10-26
    • 2019-03-21
    • 2017-09-17
    • 1970-01-01
    • 2014-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多