繁体   English   中英

自联接仅返回一条记录

[英]Self join only returning one record

在库存管理系统上工作,我们有以下表格:

================================================
| orders | order_line_items  | product_options | 
|--------|-------------------|-----------------|
| id     | id                | id              |
| start  | order_id          | name            |
| end    | product_option_id |                 |
|        | quantity          |                 |
|        | price             |                 |
|        | event_start       |                 |
|        | event_end         |                 |
================================================

我试图来计算某一特定日期的库存,所以我需要做自连接到order_line_items 数量在order_line_items与同product_option_id比较其他记录的数量的总和,并在事件开始和结束在一定范围内。

那么,鉴于2016-01-20的日期,我有:

SELECT order_line_items.id, order_line_items.product_option_id, order_line_items.order_id FROM order_line_items
WHERE order_line_items.event_end_date >= '2016-01-20 04:00:00'
AND order_line_items.event_start_date <= '2016-01-21 04:00:00'
AND order_line_items.product_option_id IS NOT NULL;

以上返回127行

当我尝试自我加入时,如下:

SELECT 
order_line_items.id, 
order_line_items.product_option_id, 
order_line_items.order_id, 
order_line_items.quantity, 

other_line_items.other_product_option_id, 
other_line_items.other_order_id, 
other_line_items.other_quantity, 
other_line_items.total 

FROM order_line_items

JOIN (
    SELECT 
        id, 
        product_option_id AS other_product_option_id, 
        order_id AS other_order_id, 
        quantity AS other_quantity, 
        SUM(quantity) total
    FROM order_line_items
    WHERE order_line_items.event_end_date >= '2016-01-20 04:00:00'
    AND order_line_items.event_start_date <= '2016-01-21 04:00:00'
) other_line_items ON order_line_items.product_option_id = other_line_items.other_product_option_id

WHERE order_line_items.event_end_date >= '2016-01-20 04:00:00'
AND order_line_items.event_start_date <= '2016-01-21 04:00:00'
AND order_line_items.product_option_id IS NOT NULL;

它只返回1条记录。 正如你在这里看到的那样:( https://goo.gl/BhUYxK )有很多记录使用相同的product_option_id,所以这最后一个查询应该返回很多行

添加的SUM(...)将子查询转换为单行。 也许子查询需要其中一个:

GROUP BY (id)
GROUP BY (product_option_id)
GROUP BY (order_id)

(我不清楚架构或应用程序是否足以说出哪些有意义。)

(请使用更短,更独特的别名;由于order_line_itemsother_line_items的长度和相似性,SQL很难阅读。)

你真的想要得到以下内容吗?

SELECT product_option_id, sum(quantity)
FROM order_line_items
WHERE event_end_date   >= '2016-01-20 04:00:00'
AND   event_start_date <= '2016-01-21 04:00:00'
GROUP BY 1

我不知道为什么你需要在这里自我加入

如果没有样本结果,很难说出你想要的东西,但这会让你比较每个订单的产品选项的数量与范围内的总数:

SELECT oli.order_id, 
       oli.product_option_id,
       oli.quantity,
       po.total_quantity   
  FROM order_line_items oli
  JOIN (
    SELECT product_option_id,
           SUM(quantity) total_quantity
      FROM order_line_items
     WHERE event_end   >= '2016-01-20 04:00:00'
       AND event_start <= '2016-01-21 04:00:00'
  GROUP BY product_option_id
       ) po
    ON po.product_option_id = oli.product_option_id
 WHERE oli.event_end   >= '2016-01-20 04:00:00'
   AND oli.event_start <= '2016-01-21 04:00:00'

如果您可以在订单中拥有相同product_option的多行,则可能需要对其进行调整:

  SELECT oli.order_id, 
         oli.product_option_id,
         SUM(oli.quantity) order_quantity,
         po.total_quantity   
    FROM order_line_items oli
    JOIN (
      SELECT product_option_id,
             SUM(quantity) total_quantity
        FROM order_line_items
       WHERE event_end   >= '2016-01-20 04:00:00'
         AND event_start <= '2016-01-21 04:00:00'
    GROUP BY product_option_id
         ) po
      ON po.product_option_id = oli.product_option_id
   WHERE oli.event_end   >= '2016-01-20 04:00:00'
     AND oli.event_start <= '2016-01-21 04:00:00'
GROUP BY oli.order_id, 
         oli.product_option_id

根据我的理解,您实际上应该将ordersproduct_options加入order_line_items表。

对于特定日期之间订单上的商品数量,您的查询应如下所示。

SELECT product_options.id, production_options.name, SUM(order_line_items.quantity)
FROM order_line_items
LEFT JOIN product_options ON production_options.id=order_line_items.product_option_id
LEFT JOIN orders ON orders.id=order_line_items.order_id
WHERE orders.start>='SOME DATETIME' AND orders.end<='SOME DATETIME'
GROUP BY product_options.id

另外,只是评论, product_options应该只是命名products 胜利的表名更短!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM