2014-06-24 5 views
0

1 시간을 소비 함에도 불구하고 해결 방법이 계속 누락되었습니다. SUM()에 대해 잘못된 데이터를 반환하는 복잡한 -is 쿼리가 있습니다. 그러나, 그것을 barest 양식으로 스트립하면 올바른 데이터를 출력합니다. 그러나 을 왜 고쳐야할지 모르겠다.스퓨리어스 (?) 값을 반환하는 MySQL SUM()

문제

SELECT po.*, SUM(poo.material_qty) AS total_items_ordered, suppliers.supplier_name 
FROM `purchase_orders` po 
LEFT JOIN purchase_orders_items poo ON poo.poid = po.poid 
LEFT JOIN suppliers ON suppliers.supplier_id = po.supplier_id 
LEFT JOIN materials_batch mb ON mb.purchase_order_no = po.poid 
WHERE po_status NOT 
IN (
'Fulfilled', 'Cancelled' 
) 
AND batch_status NOT 
IN (
'Arrived', 'Cancelled', 'Refused', 'Missing', 'Damaged', 'Completed' 
) 
GROUP BY po.poid 
ORDER BY date_expected ASC 

은 'total_items_ordered'에 대한 격렬 잘못된 데이터를 제공합니다. 나는 원시 SUM()를 쿼리에서 모든 복잡성을 제거하고 실행할 때

+-------+---------------------+---------------------+-------------+--------+-------------+--------+-----------+---------+----------+--------+----+--------+-----------+---------------------+-----------------------+ 
| poid | date_raised   | date_expected  | supplier_id | job_id | job_item_id | ref_no | sub_total | VAT  | total | userid | DN | manual | po_status | total_items_ordered | supplier_name   | 
+-------+---------------------+---------------------+-------------+--------+-------------+--------+-----------+---------+----------+--------+----+--------+-----------+---------------------+-----------------------+ 
| 15571 | 2014-06-24 13:32:55 | 2014-06-25 00:00:00 |   1 |  0 |   0 |  | 14850.10 | 2970.02 | 17820.12 |  1 | | N  | Raised |     545 | John Parker & Son Ltd | 
| 15572 | 2014-06-24 13:33:26 | 2014-06-25 00:00:00 |   1 |  0 |   0 |  | 997.80 | 199.56 | 1197.36 |  1 | | N  | Raised |     80 | John Parker & Son Ltd | 
+-------+---------------------+---------------------+-------------+--------+-------------+--------+-----------+---------+----------+--------+----+--------+-----------+---------------------+-----------------------+ 
2 rows in set (0.00 sec) 

그럼에도 불구하고,이 값은 올바른 :

mysql> SELECT poid, SUM(material_qty) AS total_items_ordered FROM `purchase_orders_items` GROUP BY poid; 
+-------+---------------------+ 
| poid | total_items_ordered | 
+-------+---------------------+ 
| 15571 |     109 | 
| 15572 |     20 | 
+-------+---------------------+ 
2 rows in set (0.00 sec) 

는 사람이 난 곳에서 어떤 빛이 있나 여기에 잘못 가고있어 ?? 제가 놓친 부분을 발견 할 수 있기 때문에 아래의 모든 테스트 테이블 내용을 포함 시켰습니다. 고맙습니다! 당신이 당신의 쿼리에서 GROUP BY을 떠날 때 잘못된 결과를

데이터 예

mysql> SELECT * FROM purchase_orders; 
+-------+---------------------+---------------------+-------------+--------+-------------+--------+-----------+---------+----------+--------+----+--------+-----------+ 
| poid | date_raised   | date_expected  | supplier_id | job_id | job_item_id | ref_no | sub_total | VAT  | total | userid | DN | manual | po_status | 
+-------+---------------------+---------------------+-------------+--------+-------------+--------+-----------+---------+----------+--------+----+--------+-----------+ 
| 15571 | 2014-06-24 13:32:55 | 2014-06-25 00:00:00 |   1 |  0 |   0 |  | 14850.10 | 2970.02 | 17820.12 |  1 | | N  | Raised | 
| 15572 | 2014-06-24 13:33:26 | 2014-06-25 00:00:00 |   1 |  0 |   0 |  | 997.80 | 199.56 | 1197.36 |  1 | | N  | Raised | 
+-------+---------------------+---------------------+-------------+--------+-------------+--------+-----------+---------+----------+--------+----+--------+-----------+ 
2 rows in set (0.00 sec) 


mysql> SELECT * FROM purchase_orders_items; 
+--------+-------+-------------+--------------+----------------+--------------+--------------------------------------------------+ 
| poi_id | poid | material_id | material_qty | material_price | material_sku | material_name         | 
+--------+-------+-------------+--------------+----------------+--------------+--------------------------------------------------+ 
|  1 | 15571 |   2 |   3 |   100.00 | PKS275282 | 406x140 White Universal Beam (S355)    | 
|  2 | 15571 |   5 |   10 |   17.40 | 118-64-44 | Test Item (S275)         | 
|  3 | 15571 |   8 |   1 |  9984.50 | 113-64-21 | A really really really big universal beam (S355) | 
|  4 | 15571 |   9 |   77 |   10.00 | 12345  | A thing           | 
|  5 | 15571 |   10 |   18 |   201.20 | 12-34-56  | 102x230 Narrow Beam (S355)      | 
|  6 | 15572 |   2 |   6 |   100.00 | PKS275282 | 406x140 White Universal Beam (S355)    | 
|  7 | 15572 |   5 |   9 |   17.40 | 118-64-44 | Test Item (S275)         | 
|  8 | 15572 |   9 |   4 |   10.00 | 12345  | A thing           | 
|  9 | 15572 |   10 |   1 |   201.20 | 12-34-56  | 102x230 Narrow Beam (S355)      | 
+--------+-------+-------------+--------------+----------------+--------------+--------------------------------------------------+ 
9 rows in set (0.00 sec) 


mysql> SELECT * FROM suppliers; 
+-------------+-----------------------+--------------------+--------------+---------------------+-------------------+-----------------------+--------------------------+---------------------+----------------------+ 
| supplier_id | supplier_name   | supplier_telephone | supplier_fax | supplier_added_date | supplier_added_by | supplier_last_updated | supplier_last_updated_by | supplier_assessed | supplier_approved_by | 
+-------------+-----------------------+--------------------+--------------+---------------------+-------------------+-----------------------+--------------------------+---------------------+----------------------+ 
|   1 | John Parker & Son Ltd | 01227 783333  | 0800 521932 | 2014-05-04 15:57:43 |     1 | 2014-06-05 16:38:23 |      1 | 2014-05-04 15:57:43 |     2 | 
|   2 | Superior Glass Ltd. | 01825 764766  | 01825 767699 | 2014-05-04 17:48:38 |     1 | 2014-06-04 20:14:16 |      1 | 2014-05-04 17:48:38 |     3 | 
|   3 | DTS Origins Ltd.  | 01283 3283029  | 01928 303494 | 2014-05-04 17:51:57 |     1 | 2014-05-04 17:53:08 |      1 | 2014-05-04 17:51:57 |     2 | 
+-------------+-----------------------+--------------------+--------------+---------------------+-------------------+-----------------------+--------------------------+---------------------+----------------------+ 
3 rows in set (0.00 sec) 


mysql> SELECT * FROM materials_batch; 
+-------------------+-------+---------------------+-------------------+------------------+-----+---------+------------+-------------+-------------+--------------+ 
| material_batch_id | poiid | rcvd_date   | purchase_order_no | delivery_note_no | qty | rcvd_by | dn_scanned | material_id | supplier_id | batch_status | 
+-------------------+-------+---------------------+-------------------+------------------+-----+---------+------------+-------------+-------------+--------------+ 
|     1 |  1 | 0000-00-00 00:00:00 |    15571 |     | 3 |  0 | No   |   2 |   1 | Ordered  | 
|     2 |  2 | 0000-00-00 00:00:00 |    15571 |     | 10 |  0 | No   |   5 |   1 | Ordered  | 
|     3 |  3 | 0000-00-00 00:00:00 |    15571 |     | 1 |  0 | No   |   8 |   1 | Ordered  | 
|     4 |  4 | 0000-00-00 00:00:00 |    15571 |     | 77 |  0 | No   |   9 |   1 | Ordered  | 
|     5 |  5 | 0000-00-00 00:00:00 |    15571 |     | 18 |  0 | No   |   10 |   1 | Ordered  | 
|     6 |  6 | 0000-00-00 00:00:00 |    15572 |     | 6 |  0 | No   |   2 |   1 | Ordered  | 
|     7 |  7 | 0000-00-00 00:00:00 |    15572 |     | 9 |  0 | No   |   5 |   1 | Ordered  | 
|     8 |  8 | 0000-00-00 00:00:00 |    15572 |     | 4 |  0 | No   |   9 |   1 | Ordered  | 
|     9 |  9 | 0000-00-00 00:00:00 |    15572 |     | 1 |  0 | No   |   10 |   1 | Ordered  | 
+-------------------+-------+---------------------+-------------------+------------------+-----+---------+------------+-------------+-------------+--------------+ 
+0

을 내 SQL은 예기치 않은 결과를 반환 할 수있는 확장 된 그룹을 가지고 있습니다. 확장 된 그룹을 기준으로 사용하지 않도록 설정하거나 그룹의 집계되지 않은 모든 필드를 기준으로 정의하십시오. [docs] (http://dev.mysql.com/doc/refman/5.0/en/group-by-extensions.html) "서버는 각 그룹의 값을 자유롭게 선택할 수 있으므로 동일하지 않은 한, 선택된 값은 불확정하다. " 둘째, 조인으로 인해 구매 주문 항목에 추가 레코드가 표시 될 수 있습니다. PO 당 1 레코드 이상 공급 업체 또는 자재 배치가 있습니까? 그렇다면 문제도 그 원인이됩니다. – xQbert

+0

sqlfiddle.com 링크를 제공해야 사람들이 더 많은 것을 도와 줄 수 있습니다. –

+0

@VishalZanzrukia sqlfiddle은 (는) 존재하지 않았습니다 ... 다음에 주목했습니다! 고마워요 :) –

답변

2

이유는 명확해야한다. JOIN 각 테이블에 대해 반환 된 행 수는 JOIN에서 찾은 행 수를 곱합니다. materials_batch 표 순서에 따라 복수의 엔트리를 포함 같이

가 생성 total_items_ordered은 주문 번호 15,571 5 승산, 및는 다음 시도 15572.

주문 번호 (4)에 의해 승산된다 :

SELECT 
    po.*, 
    (
     SELECT SUM(poo.material_qty) 
     FROM purchase_orders_items poo 
     WHERE poo.poid = po.poid 
    ) AS total_items_ordered, 
    suppliers.supplier_name 
FROM `purchase_orders` po 
LEFT JOIN suppliers ON suppliers.supplier_id = po.supplier_id 
LEFT JOIN materials_batch mb ON mb.purchase_order_no = po.poid 
WHERE po_status NOT 
IN (
'Fulfilled', 'Cancelled' 
) 
AND batch_status NOT 
IN (
'Arrived', 'Cancelled', 'Refused', 'Missing', 'Damaged', 'Completed' 
) 
GROUP BY po.poid 
ORDER BY date_expected ASC 
+0

그건 실제로 많은 의미가 있습니다. 다음 질문은 ...이 문제를 해결하는 쉬운 방법이 있습니까? –

+0

하위 선택을 시도 할 수 있습니다. 내 업데이트 답변을 참조하십시오. – bspellmeyer

+0

전설! 그것은 절대적인 매력처럼 작동합니다. 고맙습니다! :) –