首页 > 解决方案 > MySQL 使用带有 IN 子查询的 CASE WHEN

问题描述

这是对我要完成的工作的简要说明;我的查询如下。

我有两张桌子,一张有 500 个产品product_limit500,另一张有订单order_limit1000

我的目标是为每个订单创建一个包含所有 500 种产品的表,所有产品都以相同的顺序(如order one followed by all other products,然后order two followed by the products in the same order)。

这是我尝试使用的查询。

SELECT 
  r1.order_id, 
  r1.product_id, 
  r1.product_name,
  CASE WHEN p1.product_id IN (SELECT 
                                r2.product_id 
                              FROM 
                                order_limit1000 r2 
                              WHERE 
                                r2.order_id = r1.order_id) THEN 's'
  ELSE '?'
  END as 'torf'
FROM 
  order_limit1000 r1, 
  product_limit500 p1;

这是目前的结果。

  order_id  product_id  product_name    torf
   5    13176   Bag of Organic Bananas  ?
   5    13176   Bag of Organic Bananas  s
   5    13176   Bag of Organic Bananas  ?
   5    13176   Bag of Organic Bananas  ?
   5    13176   Bag of Organic Bananas  s
   5    13176   Bag of Organic Bananas  ?
   5    13176   Bag of Organic Bananas  ?
   5    13176   Bag of Organic Bananas  ?
   5    13176   Bag of Organic Bananas  ?
   5    13176   Bag of Organic Bananas  ?
   5    13176   Bag of Organic Bananas  s
   5    13176   Bag of Organic Bananas  ?
   ...

感谢您的任何帮助,您可以提供。

...

现在我正在使用 500products和 1000 行的视图orders,我仍在考虑最终大小是多少orders,可能是 500k 到 1mi 行。但是我使用的数据集有 4.5mi 行。

预期的结果将如下所示。

 order_id   product_id  product_name    torf
    5           123        tomatoes      s
    5           124        limes         ?
    ...
    100         123        tomatoes      ?
    100         124        limes         ?

标签: mysql

解决方案


不要在表名之间使用逗号,当然也不要这样做来代替cross join. 我不确定为什么您希望每个产品都针对每个订单,但要做到这一点,您确实需要一个完整的笛卡尔产品,因此您需要一个交叉连接。

SELECT
    r1.order_id
  , p1.product_id
  , p1.product_name
  , CASE
        WHEN r1.product_id = p1.product_id THEN 's'
        ELSE '?'
    END AS 'torf'
FROM order_limit1000 r1
CROSS JOIN product_limit500 p1
ORDER BY
    r1.order_id
  , p1.product_id
  , p1.product_name

鉴于 order 表中已经有 product_id,您不需要另一个相关子查询来测试您是否应该输出 's' 或 '?'。注意:我假设产品名称来自产品表,而不是订单表。

  order_id   R1.product_id   P1.product_id   product_name   torf  
 ---------- --------------- --------------- -------------- ------ 
         5             123             123   tomatoes       s     << r1.product_id = p1.product_id
         5                             124   limes          ?     
       ...                                                        
       100                             123   tomatoes       ?     
       100                             124   limes          ?     

推荐阅读