【问题标题】:SQL How to find carts that only contain specific cart items?SQL 如何查找仅包含特定购物车项目的购物车?
【发布时间】:2013-10-26 03:06:41
【问题描述】:

假设我有两张桌子,桌子购物车和购物车项目。一个购物车可以有一个或多个 cart_items。

Cart_items 是从 items 表中“模板化”的。对于多个 cart_items,像 item_name 这样的属性将是相同的。我想创建一个查询,该查询返回包含名为 Apple AND Banana AND Carrot 的购物车项目的所有购物车(所有购物车属性,而不仅仅是 id)。

以下是我尝试过的几个示例。

Table cart 
cart_id_pk
cart_desc
cart_total
etc...

Table cart_item
item_id
item_name
cart_id_fk 

我的第一次尝试:

SELECT * FROM cart_item ci
LEFT JOIN cart c
ON ci.cart_id_fk = c.cart_id
WHERE ci.item_name = 'Apple' AND ci.item_name = 'Banana' AND ci.item_name = 'Carrot'
GROUP BY c.cart_id_pk

这行不通,因为选择中的每一行只包含一个 cart_item。

我的第二次尝试:

WHERE ci.item_name = 'Apple' OR ci.item_name = 'Banana' OR ci.item_name = 'Carrot'

这也不起作用,因为它会返回至少包含其中任何一个 cart_items 的购物车。

现在正在修改子查询.. 不确定我是否走在正确的轨道上。

帮助表示赞赏。

【问题讨论】:

    标签: sql


    【解决方案1】:

    你需要有

    WHERE c.cart_id_pk IN (
        SELECT ci.cart_id_fk 
        FROM cart_item ci 
        WHERE ci.item_name = "Apple")
    AND c.cart_id_pk IN (
        SELECT ci.cart_id_fk 
        FROM cart_item ci 
        WHERE ci.item_name = "Banana")
    AND c.cart_id_pk IN (
        SELECT ci.cart_id_fk 
        FROM cart_item ci 
        WHERE ci.item_name = "Carrot")
    

    WHERE 声明...

    这应该可行。

    【讨论】:

    • 如果您需要多于或少于 3 行,我会编写一些动态 SQL 以通过传入参数迭代 where 子句。
    • 这种方法效果很好。你的例子有点不对劲,在 IN 之前的 ci.cart_id_pk 应该是 ci.cart_id_fk 或 c.cart_id_pk。
    【解决方案2】:

    您可以使用COUNT(*) 子句对子查询中的匹配项进行计数,如下所示:

    SELECT * 
    FROM   cart c
    WHERE  cart_id IN (SELECT    cart_id_fk
                       FROM      cart_item
                       WHERE     item_name IN ('Apple', 'Banana', 'Carrot')
                       GROUP BY  cart_id_fk
                       HAVING    COUNT(*) = 3 /* number of matching items*/ )
    

    注意:此解决方案假定同一个购物车不能有多个苹果。根据 OP,不确定这是否可以。

    【讨论】:

    • 不会有多个苹果。我运行了这个查询,但它从未完成,几分钟后我中断了执行。我运行了 Amber 的查询,不到一秒就成功执行了。计数功能会导致性能问题吗?我的 cart 表中有大约 20,000 条记录,items 表中有 40,000 条记录。
    • HAVING 子句中的 COUNT(*) 在性能方面可能是个坏主意。我想知道将其更改为 EXISTS 语义而不是 IN 是否会有所作为...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-11
    • 2011-04-09
    • 1970-01-01
    相关资源
    最近更新 更多