0

我有一个像这样的表模式。

mysql> desc material_out;

+-------------+--------------+------+-----+---------+-------+
| Field       | Type         | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| id          | int(11)      | NO   |     | 0       |       |
| barcode     | varchar(20)  | NO   |     | NULL    |       |
| name        | varchar(100) | NO   |     | NULL    |       |
| qty         | double       | YES  |     | NULL    |       |
| unit        | varchar(20)  | YES  |     | NULL    |       |
| num_letter  | varchar(30)  | YES  |     | NULL    |       |
| date        | date         | YES  |     | NULL    |       |
| destination | varchar(50)  | YES  |     | NULL    |       |
+-------------+--------------+------+-----+---------+-------+
8 rows in set (0.00 sec)

mysql> desc material_in;

+-------------+--------------+------+-----+---------+-------+
| Field       | Type         | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| id          | int(11)      | NO   |     | 0       |       |
| barcode     | varchar(20)  | NO   |     | NULL    |       |
| name        | varchar(100) | NO   |     | NULL    |       |
| qty         | double       | YES  |     | NULL    |       |
| unit        | varchar(20)  | YES  |     | NULL    |       |
| num_letter  | varchar(30)  | YES  |     | NULL    |       |
| date        | date         | YES  |     | NULL    |       |
| destination | varchar(50)  | YES  |     | NULL    |       |
+-------------+--------------+------+-----+---------+-------+
8 rows in set (0.00 sec)

mysql> desc goods;

+-------------+--------------+------+-----+---------+-------+
| Field       | Type         | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| id          | int(11)      | NO   |     | 0       |       |
| barcode     | varchar(20)  | NO   |     | NULL    |       |
| name        | varchar(100) | NO   |     | NULL    |       |
| unit        | varchar(20)  | YES  |     | NULL    |       |
| category    | varchar(25)  | YES  |     | NULL    |       |
| first_stok  | double    )  | YES  |     | NULL    |       |
+-------------+--------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

在表 material_out 我有 10,000 行的数据。并拥有多达 350 种条码。在表 material_in 中,我有大约 15,000 行的数据。并拥有多达 200 种条码。

我的查询是这样的

SELECT br.barcode,
    COALESCE(tNEW.total_out,0) AS total_out, COALESCE(tNEW.total_in,0) as total_in,
    COALESCE(tNEW.total_in,0)-COALESCE(tNEW.total_out,0) AS result,
    COALESCE(tOLD.total_out,0) AS total_out_old, COALESCE(tOLD.total_in,0) AS total_in_old
FROM (
SELECT barcode from goods where category=1
) as br
LEFT JOIN (
    SELECT goods.barcode,
        COALESCE(SUM(tOUT.qty),0) AS total_out,
        COALESCE(SUM(tIN.qty),0) AS total_in
    FROM goods
    LEFT JOIN material_out AS tOUT ON tOUT.barcode=goods.barcode
    LEFT JOIN material_in AS tIN ON tIN.barcode=goods.barcode
    WHERE goods.category=1
        AND tOUT.date >='2013-05-01' AND tOUT.date <='2013-08-31'
        AND tIN.date >= '2013-05-01' AND tIN.date <= '2013-08-31'
    GROUP BY goods.barcode
) AS tNEW ON tNEW.barcode=br.barcode
LEFT JOIN (
    SELECT goods.barcode,
        SUM(tOUT.qty) AS total_out,
        SUM(tIN.qty) AS total_in
    FROM goods
    LEFT JOIN material_out AS tOUT ON tOUT.barcode=goods.barcode
    LEFT JOIN material_in AS tIN ON tIN.kode=goods.barcode
    WHERE goods.category=1
        AND tOUT.date BETWEEN '2013-01-01' AND '2013-04-31'
        AND tIN.date BETWEEN '2013-01-01' AND '2013-04-31'
    GROUP BY goods.barcode
) AS tOLD ON tOLD.barcode=br.barcode

我用过这样的查询。结果进展顺利。但是当我尝试输入新数据时。然后我重新查询你的显示。但结果与输入的数据不符。例如,当我输入您的查询时。以下结果

+--------------+-----------+----------+------------+---------------+-------------------+
|    barcode   | total_out | total_in | result     | total_out_old | total_in_old      |
+--------------+-----------+----------+------------+---------------+-------------------+
| TNWET021     |      6195 |    15000 |       8805 |         20085 |             46200 |
| TNWET020     |      3420 |     7650 |       4230 |          4860 |             23925 |
| TNWET019     |      8370 |    25200 |      16830 |         11610 |             47175 |
| TNWET018     |     18690 |    44100 |      25410 |         13800 |             54150 |
| TNWET017     |      1140 |     3750 |       2610 |          3690 |             16200 |
| TNWET016     |     19500 |    56100 |      36600 |         31725 |            111300 |
| TNWET015     |      5145 |    18150 |      13005 |          6510 |             23400 |
| TNWET014     |     33300 |    65250 |      31950 |         96300 |            262500 |
| TNWET013     |      1170 |     5625 |       4455 |          3690 |             13200 |
| TNWET012     |       720 |     2700 |       1980 |          3870 |             13800 |
| TNWET011     |         0 |        0 |          0 |           180 |               450 |
| TNWET010     |         0 |        0 |          0 |           405 |              1125 |
| TNWET009     |         0 |        0 |          0 |             0 |                 0 |

当我进行手动求和并得到这样的结果时。

mysql> select sum(qty) from material_in where barcode='TNWET021' and date BETWEEN '2013-05-01' AND '2013-08-31';
+-------------+
|   sum(qty)  |
+-------------+
|         750 |
+-------------+
1 row in set (0.00 sec)

mysql> select sum(qty) from material_in where barcode='TNWET020' and date BETWEEN '2013-05-01' AND '2013-08-31';
+-------------+
|   sum(qty)  |
+-------------+
|         450 |
+-------------+
1 row in set (0.00 sec)

当数据对于报告非常重要时,为什么结果可能会有很大不同。请帮我。

我之前使用过这个,但是执行需要很长时间。也许您可以帮助总结此查询以快速执行

SELECT COALESCE(tIN.total_in,0) + COALESCE(production.total_prod,0) AS incoming, COALESCE(tOUT.total_out,0) AS expenditure,br.barcode as barcode, br.name,br.initial_stock,br.unit,COALESCE(adj.total,0) AS adjusment,COALESCE(tIN.total_in,0) + COALESCE(production.total_prod,0) + COALESCE(adj.total,0) + COALESCE(br.intial_stock,0) - COALESCE(tOUT.total_out,0) as final_stok,so.stock_opname from (
select barcode,name,initial_stock,unit from barang where category=1
) as br
LEFT JOIN (
select (select sum(qty) from material_out where date >= '2013-05-01' AND date <='2013-08-31' and barcode=a.barcode) as total_out,a.barcode from material_out a group by a.barcode
) as tOUT
ON tOUT.barcode=br.barcode
LEFT JOIN
(
SELECT(
SELECT SUM(qty) FROM adjusment
WHERE status = '+' AND date >= '2013-05-01' AND date <= '2013-08-31'
) - (
SELECT SUM(qty) FROM adjusment
WHERE status = '-' AND date >= '2013-05-01' AND date <= '2013-08-31'
) AS total,barcode FROM adjusment
GROUP BY barcode
) AS adj
ON br.barcode = adj.barcode
LEFT JOIN (
select (select sum(qty) from material_in where date >= '2013-05-01' AND date <='2013-08-31' and barcode=a.barcode) as total_in,a.barcode,a.nama from material_in a group by a.barcode
) as tIN
ON br.barcode=tIN.barcode
LEFT JOIN (
select (select sum(qty) from view_production where date >= '$start' AND date <='$end' and kode=a.kode) as total_prod,a.barcode from view_production a group by a.barcode
) as production
ON br.barcode=production.barcode

LEFT JOIN (
select(select sum(qty) from stock_opname where date >= '2013-04-01' AND date <= '2013-05-31' AND barcode=a.barcode) as stok_opname,a.barcode from pencacahan a group by a.barcode
) as so
ON br.barcode=so.barcode

我会给予奖励来解决我的问题

4

1 回答 1

0

请看下面的例子:

Table A: 2 records: code = ["TNWET020", "TNWET021"]
Table B: 2 records: (code, val) = [("TNWET021", 1), ("TNWET021", 2)]
Table C: 2 records: (code, val) = [("TNWET021", 11), ("TNWET021", 12)]   
~~~~
SQL 1:
SELECT A.code, sum(B.val)
FROM A left join B on A.code = B.code;
==> 3 ==> OK.

SQL 2:
SELECT A.code, sum(B.val)
FROM A left join B on A.code = B.code left join C on A.code = C.code;
==> 6

==> 在你的 sql 中,左连接 material_in 和 material_out 会产生重复数据。


对于第二个查询,我认为我们有 2 点需要改进。
删除不必要的嵌套查询:

LEFT JOIN (
select (select sum(qty) from material_out where date >= '2013-05-01' AND date <='2013-08-31' and barcode=a.barcode) as total_out,a.barcode from material_out a group by a.barcode
) as tOUT
==>
LEFT JOIN (select sum(qty) as total_out, barcode from material_out where date >= '2013-05-01' AND date <='2013-08-31' group by a.barcode
) as tOUT


尝试删除连接,因为连接占用大量内存:
Ex 而不是:

SELECT A.code, sum(B.val) FROM A left join B on A.code = B.code
==> 
select A.code, (select sum(B.val) from B where B.code = A.code) as bVal from A;
于 2013-11-12T10:02:40.910 回答