簡體   English   中英

聯接另一個表時發生聯接表中列的SUM錯誤

[英]Incorrect SUM of column from JOINed table occurs when JOINing another table

我想從表中的每個記錄ProductItem ,並為他們每個人,讓現場的總和units_in_stock從表ProductAttrsInfo ,與主表中加入一些父和子表。

我要檢索的完整字段是:

  • ProductItem.id AS product_item_id
  • ProductItem.name AS product_item_name
  • SUM(ProductAttrsInfo.units_in_stock) AS units_in_stock
  • IFNULL(SUM(TransOrderItem.quantity), 0) AS total_ordered_items

當然,要獲得total_ordered_items ,我需要加入TransOrderItem ,但是當我加入它時,總和結果是不正確的。

這是表關系圖:

  +-----------+
  |ProductType|
  +-----+-----+
        | 1-M
        v
 +--------------+       +----------+
 |ProductSubtype|       |TransOrder|
 +------+-------+       +-----+----+
        | 1-M                 | 1-M
        v                     v
  +-----------+       +--------------+
  |ProductItem|       |TransOrderItem|
  +-----+-----+       +-------+------+
        | 1-M                 | 1-M
        v                     |
  +-----------+               |
  |ProductAttr|<--------------+
  +-----+-----+
        | 1-1
        v
+----------------+
|ProductAttrsInfo|
+----------------+

這是不加入表TransOrderItem的查詢:

SELECT 
    ProductSubtype.id AS product_subtype_id,
    ProductItem.id AS product_item_id,
    ProductItem.name AS product_item_name,
    SUM(ProductAttrsInfo.units_in_stock) AS units_in_stock
FROM 
    product_items AS ProductItem
LEFT JOIN product_attrs AS ProductAttr ON
    ProductItem.id = ProductAttr.product_item_id
LEFT JOIN product_attrs_infos AS ProductAttrsInfo ON
    ProductAttr.id = ProductAttrsInfo.product_attr_id
RIGHT JOIN product_subtypes AS ProductSubtype ON
    ProductSubtype.id = ProductItem.product_subtype_id
RIGHT JOIN product_types AS ProductType ON
    ProductType.id = ProductSubtype.product_type_id
GROUP BY 
    ProductItem.id
ORDER BY 
    ProductSubtype.id ASC,
    ProductItem.id ASC

以上查詢的結果,是正確的:

    +------------------------------------------------------------------------------+
    | product_item_id | product_item_name                         | units_in_stock |
    +------------------------------------------------------------------------------+
    |               1 | Kaos Pria O-Neck                          |           6935 |
    |               2 | Kaos Pria Two-Tone                        |           1999 |
    |              10 | Kaos Pria - Gildan 63000 Soft Style       |           1163 |
    |              30 | Kaos Pria | Gildan 64V00 - VNeck          |             48 |
    |              31 | Kaos Pria - Gildan 76400 - Lengan Panjang |            522 |
    |             130 | Kaos Pria V-Neck                          |            574 |
    |             ... | ...                                       |            ... |
    +------------------------------------------------------------------------------+

這是帶有TransOrderItem表的查詢:

SELECT 
    ProductSubtype.id AS product_subtype_id,
    ProductItem.id AS product_item_id,
    ProductItem.name AS product_item_name,
    SUM(ProductAttrsInfo.units_in_stock) AS units_in_stock,
    IFNULL(SUM(TransOrderItem.quantity), 0) AS total_ordered_items
FROM
    product_items AS ProductItem
INNER JOIN product_attrs AS ProductAttr ON 
    ProductItem.id = ProductAttr.product_item_id
INNER JOIN product_attrs_infos AS ProductAttrsInfo ON
    ProductAttr.id = ProductAttrsInfo.product_attr_id
LEFT JOIN trans_order_items AS TransOrderItem ON
    ProductAttr.id = TransOrderItem.product_attr_id AND
    (TransOrderItem.created BETWEEN '2017-12-01' AND '2017-12-31') AND
    EXISTS (
        SELECT 1 FROM trans_orders AS TransOrder
        WHERE 
            TransOrderItem.trans_order_id = TransOrder.id AND
            TransOrder.status = 'TRS_SHP_FNS'
    )
INNER JOIN product_subtypes AS ProductSubtype ON 
    ProductSubtype.id = ProductItem.product_subtype_id
INNER JOIN product_types AS ProductType ON 
    ProductType.id = ProductSubtype.product_type_id
GROUP BY 
    ProductItem.id
ORDER BY 
    ProductSubtype.id ASC,
    ProductItem.id ASC

上述查詢的結果,其中units_in_stock總和不正確:

    +-----------------+-------------------------------------------+----------------+
    | product_item_id | product_item_name                         | units_in_stock |
    +------------------------------------------------------------------------------+
    |               1 | Kaos Pria O-Neck                          |          51285 |
    |               2 | Kaos Pria Two-Tone                        |           6175 |
    |              10 | Kaos Pria - Gildan 63000 Soft Style       |           9532 |
    |              30 | Kaos Pria | Gildan 64V00 - VNeck          |             48 |
    |              31 | Kaos Pria - Gildan 76400 - Lengan Panjang |           3047 |
    |             130 | Kaos Pria V-Neck                          |            937 |
    |             ... | ...                                       |            ... |
    +-----------------+-------------------------------------------+----------------+

查詢中是否有任何錯誤的操作導致總和不正確? 帶有說明的正確查詢將作為答案。 謝謝。

-

編輯 :添加表結構:

`product_attrs` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `product_item_id` int(10) unsigned NOT NULL DEFAULT '0',
  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_product_attrs_product_items` (`product_item_id`),
  CONSTRAINT `fk_product_attrs_product_items` FOREIGN KEY (`product_item_id`) REFERENCES `product_items` (`id`)
)

`product_attrs_infos` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `product_attr_id` int(10) unsigned NOT NULL DEFAULT '0',
  `units_in_stock` int(10) NOT NULL DEFAULT '0',
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `product_attr_id` (`product_attr_id`),
  CONSTRAINT `fk_product_attrs_info_product_attr_id` FOREIGN KEY (`product_attr_id`) REFERENCES `product_attrs` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
)

`product_items` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8 NOT NULL DEFAULT '',
  `product_subtype_id` int(10) unsigned NOT NULL DEFAULT '0',
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `product_subtype_id` (`product_subtype_id`),
  CONSTRAINT `product_items_ibfk_1` FOREIGN KEY (`product_subtype_id`) REFERENCES `product_subtypes` (`id`)
)

`trans_orders` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `status` enum('TRS_OPN','TRS_PAID','TRS_RFD','TRS_EXPR','TRS_INPROCESS','TRS_SHP_OPN','TRS_SHP_FNS','TRS_HOLD') DEFAULT 'TRS_OPN',
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
)

`trans_order_items` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `trans_order_id` int(10) unsigned NOT NULL,
  `product_attr_id` int(10) unsigned NOT NULL DEFAULT '0',
  `status` enum('TRS_OPN','PRNT_OPN','PRNT_FNS','QA_OPN','QA_PASS','QA_FAIL','PRNT_FAIL_OPN','PRNT_FAIL_FNS') NOT NULL DEFAULT 'TRS_OPN',
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_trans_order_items_trans_order_id` (`trans_order_id`),
  KEY `fk_to_items_product_attr_id` (`product_attr_id`),
  CONSTRAINT `fk_to_items_product_attr_id` FOREIGN KEY (`product_attr_id`) REFERENCES `product_attrs` (`id`),
  CONSTRAINT `fk_trans_order_items_trans_order_id` FOREIGN KEY (`trans_order_id`) REFERENCES `trans_orders` (`id`)
)

您需要在單獨的子條款中根據total_ordered_items計算數量,然后對主查詢進行左連接,以避免此類問題

SELECT 
    st.id AS product_subtype_id,
    i.id AS product_item_id,
    i.name AS product_item_name,
    SUM(ai.units_in_stock) AS units_in_stock,
    IFNULL(oi.total_ordered_items, 0) AS total_ordered_items
FROM
    product_items AS i
INNER JOIN product_attrs AS a ON 
    i.id = a.product_item_id
INNER JOIN product_attrs_infos AS ai ON
    a.id = ai.product_attr_id
INNER JOIN product_subtypes AS st ON 
    st.id = i.product_subtype_id
INNER JOIN product_types AS t ON 
    t.id = st.product_type_id
LEFT JOIN (
    SELECT toi.product_attr_id, 
           SUM(toi.quantity) total_ordered_items
    FROM trans_order_items as toi
    WHERE toi.created BETWEEN '2017-12-01' AND '2017-12-31'
    AND EXISTS (
        SELECT 1 
        FROM trans_orders AS o
        WHERE toi.trans_order_id = o.id 
        AND o.status = 'TRS_SHP_FNS'
    )
    GROUP BY toi.product_attr_id
) as oi ON a.id = oi.product_attr_id
GROUP BY
    st.id, 
    i.id,
    i.name
ORDER BY 
    st.id ASC,
    i.id ASC

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM