简体   繁体   English

MySQL 多个表中多行的总和

[英]MySQL SUM of multiple rows from multiple table

I am trying to get the sum of multiple rows from 2 different tables, but somehow the result returns multiple rows.我试图从 2 个不同的表中获取多行的总和,但结果以某种方式返回了多行。

I need to get the SUM of quotation_item_amount (group by quotation_id) and invoice_item_amount (group by invoice_id) and if I query unpaid quotation, I need to get WHERE SUM(invoice) < SUM(quotation)我需要获取 quotation_item_amount(按 quotation_id 分组)和 invoice_item_amount(按 invoice_id 分组)的总和,如果我查询未付报价,我需要获取 WHERE SUM(invoice) < SUM(quotation)

So here's my sample table所以这是我的示例表

table client_project_id
+-------------------+-----------+----------------------+
| client_project_id | client_id | client_project_title |
+-------------------+-----------+----------------------+
|         23        |     5     |        Project 1     |
|         17        |     9     |        Project 2     |
|         54        |     7     |        Project 3     |
+-------------------+-----------+----------------------+

table quotation
+--------------+-------------------+------------------+
| quotation_id | client_project_id | quotation_number |
+--------------+-------------------+------------------+
|       1      |          23       |   Q/01/2020/001  |
|       2      |          17       |   Q/01/2020/002  |
|       3      |          54       |   Q/01/2020/003  |
+--------------+-------------------+------------------+

table quotation_item
+-------------------+--------------+-----------------------+
| quotation_item_id | quotation_id | quotation_item_amount |
+-------------------+--------------+-----------------------+
|         1         |     1        |          500          |
|         2         |     1        |          700          |
|         3         |     1        |          600          |
|         4         |     2        |          200          |
|         5         |     2        |          150          |
|         6         |     3        |          900          |
+-------------------+--------------+-----------------------+

table invoice
+--------------+-------------------+------------------+
|  invoice_id  | client_project_id |  invoice_number  |
+--------------+-------------------+------------------+
|       1      |          23       |   I/01/2020/001  |
|       2      |          17       |   I/01/2020/002  |
|       3      |          54       |   I/01/2020/003  |
+--------------+-------------------+------------------+

table invoice_item
+-------------------+--------------+-----------------------+
|  invoice_item_id  |  invoice_id  |  invoice_item_amount  |
+-------------------+--------------+-----------------------+
|         1         |     1        |          500          |
|         2         |     1        |          700          |
|         3         |     1        |          600          |
|         4         |     2        |          200          |
|         5         |     2        |          150          |
|         6         |     3        |          900          |
+-------------------+--------------+-----------------------+

The result that I need to obtain is:我需要得到的结果是:

  1. SUM of quotation_item_amount and SUM of invoice_item_amount PER client_project_id quotation_item_amount 的 SUM 和 invoice_item_amount 的 SUM PER client_project_id
  2. To query WHERE SUM(invoice) < SUM(quotation)查询 WHERE SUM(invoice) < SUM(quotation)

Here is my latest try at the query这是我最近的查询尝试

SELECT 
    SUM(quotation_item.quotation_item_amount) as quot_amt, 
    SUM(invoice_item.invoice_item_amount) as inv_amt,
    data_client_project.client_project_id,
    data_client.client_name

FROM data_client_project a
LEFT JOIN quotation b ON a.client_project_id = b.client_project_id
LEFT JOIN data_client d ON a.client_id = d.client_id
LEFT JOIN invoice i ON a.client_project_id = i.client_project_id
JOIN (
        SELECT quotation_id, 
            SUM(c.quotation_item_amount) as quot_amt
        FROM quotation_item c 
        GROUP BY c.quotation_id
      ) quotitem
        ON b.quotation_id = quotitem.quotation_id
        JOIN (
            SELECT invoice_id, 
                SUM(e.invoice_item_price) as inv_amt
            FROM invoice_item e
            GROUP BY e.invoice_id
        ) invitem
        ON i.invoice_id = invitem.invoice_id

However, this results in multiple duplicate rows of the quotation_item_amount and invoice_item_amount.但是,这会导致 quotation_item_amount 和 invoice_item_amount 的多个重复行。

Have tried using UNION / UNION ALL and several other queries which just do not work.已尝试使用 UNION / UNION ALL 和其他几个不起作用的查询。 Thank you for all your suggestions.谢谢你的所有建议。

It looks like you are trying to aggregate along two different dimensions at the same time.看起来您正在尝试同时沿两个不同的维度进行聚合。 The solution is to pre-aggregate along each dimension:解决方案是沿每个维度进行预聚合:

SELECT *
FROM data_client_project cp LEFT JOIN
     (SELECT q.client_project_id,
             SUM(qi.quotation_item_amount * qi.quotation_item_qty) as quot_amt
      FROM quotation q JOIN
           quotation_item qi
           ON qi.quotation_id = q.quotation_id
      GROUP BY q.client_project_id
     ) q
     USING (client_project_id) LEFT JOIN
     (SELECT i.client_project_id,
             SUM(invoice_item_price) as inv_amt
      FROM invoice i JOIN
           invoice_item ii
           ON i.invoice_id = ii.invoice_id
      GROUP BY i.client_project_id
     ) i
     USING (client_project_id);

Two notes about your style.关于您的风格的两个注意事项。

First, you are using arbitrary letters for table aliases.首先,您使用任意字母作为表别名。 This makes the query quite hard to follow and becomes quite awkward if you add new tables, remove tables, or rearrange the names.如果您添加新表、删除表或重新排列名称,这会使查询很难遵循并且变得很尴尬。 Use abbreviations for the tables.对表格使用缩写。 Much easier to follow.更容易遵循。

Second, I don't really recommend SELECT * for such queries.其次,我真的不推荐SELECT *用于此类查询。 But, you can avoid duplicated column by replacing ON with USING .但是,您可以通过将ON替换为USING来避免重复的列。

I may be missing something, but your table descriptions do not include a example for data_client or data_client_project Given your example, I expect your row expansion is coming from the first 3 joins.我可能遗漏了一些东西,但您的表描述不包括data_clientdata_client_project的示例根据您的示例,我希望您的行扩展来自前 3 个连接。

Make sure that the below is giving you the list of data you want first, then try joining in the calculation:确保下面首先为您提供所需的数据列表,然后尝试加入计算:

SELECT *
    FROM data_client_project a
    LEFT JOIN quotation b ON a.client_project_id = b.client_project_id
    LEFT JOIN data_client d ON a.client_id = d.client_id
    LEFT JOIN invoice i ON a.client_project_id = i.client_project_id;
#you may want to append the above with a limit 100 for testing.

if you have duplicated rows form the main query then add distinct for obatin a only distinct rows and andd the where conditio for filtering the result by quotitem.quot_amt < invitem.inv_amt如果您在主查询中有重复的行,则为 obatin 添加不同的行,并且添加用于通过 quotitem.quot_amt < invitem.inv_amt 过滤结果的条件

    SELECT distinct a.*, b.*, d.*, i.*  
    FROM data_client_project a
    LEFT JOIN quotation b ON a.client_project_id = b.client_project_id
    LEFT JOIN data_client d ON a.client_id = d.client_id
    LEFT JOIN invoice i ON a.client_project_id = i.client_project_id
    JOIN (
            SELECT quotation_id, 
                SUM(c.quotation_item_amount * c.quotation_item_qty) as quot_amt
            FROM quotation_item c 
            GROUP BY c.quotation_id
          ) quotitem  ON b.quotation_id = quotitem.quotation_id
    JOIN (
            SELECT invoice_id, 
                SUM(e.invoice_item_price) as inv_amt
            FROM invoice_item e
            GROUP BY e.invoice_id
            ) invitem  ON i.invoice_id = invitem.invoice_id
    WHERE quotitem.quot_amt < invitem.inv_amt

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

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