MySQL:如何在复杂的连接查询中对不同的行求和

时间:2014-01-10 22:34:46

标签: mysql sum join

我有MySQL问题我无法解决自己(第一次)。

我有一个带参数的查询数据库和PHP程序,它们一起生成大量的MySQL查询来运行。

问题实际上是一个简单的问题:正确求和的问题。我需要在复杂的多连接查询中SUM个不同的行(而不是值),我无法使其工作。

不要问为什么我使用下面的数据结构 - 我正在处理提供给我的数据,它需要这样。 (表格代表现有发票。)

我将尝试重现这里非常简化的情况。

TABLE INVOICE
=============
Inv.Nr (ID)   Other Data
------------------------
#1            Stuff
#2            Stuff
#3            More Stuff

TABLE INVOICE LINE
==================
ID   Inv.Nr    QUANTITY  ArticleID  UNIT PRICE
----------------------------------------------
1      #1        1        5          € 2.50
2      #1        1        109        € 4.00
3      #2        4        77         € 5.00
4      #2        10       91         € 6.00

TABLE INVOICE LINE VAT
======================
ID   LINE-ID   AMOUNT  VATP  VAT
1      1       € 2.00  25%   € 0.50
2      2       € 2.00  25%   € 0.50
3      2       € 1.42   6%   € 0.08
4      3       €18.87   6%   € 1.23
5      4       €16.00  25%   € 4.00
6      4       €37.74   6%   € 2.26

正如您所看到的:某些文章的增值税率为双倍,因为它们包含更多具有不同增值税税率的元素(即带有CD的图书)。

现在查询很长,加入的表更多,可以有动态WHERE和GROUP BY子句。因此,查询可能看起来有点像(再次简化):

SELECT `Inv.Nr`, ArticleID, SUM(Quantity), SUM(Amount), SUM(VAT)
FROM ((((`Invoice` INNER JOIN `Invoice Line` 
           ON `Invoice`.`Inv.Nr`=`Invoice Line`.`Inv.Nr`)
      INNER JOIN `Invoice Line VAT` 
           ON `Invoice Line`.ID = `Invoice Line VAT`.`Line-ID`)
      INNER JOIN `More Stuff`
           ON .... )
      INNER JOIN ....
           ON ..... )
WHERE ....
GROUP BY .....
HAVING .....

由...定义的INNER JOIN是多对1,因此Invoice Line VAT位于其两个JOIN关系的多边。

WHEREGROUP BYHAVING是在PHP代码中半动态创建的。

我的问题是,我无法同时获得正确的SUM(Amount)SUM(Quantity),因为如果一个发票行有多个增值税税率,则会多次添加Quantity

  • SUM(DISTINCT Quantity)显然不起作用,因为我需要不同的行,而不是值。
  • 我无法创建一个子查询来计算增值税税率(并划分SUM(Quantity)),或计算Amount,因为子查询需要与主要相同的WHERE / HAVING参数查询工作正常,这些是半动态的(查询在数据库中,包含按照用户命令填写的参数)。好吧,公平地说,我可以做到,但它会让查询数据库和php软件变得非常复杂,而且我不想为这么简单的问题使用非常复杂的解决方案,特别是因为其他人会必须在将来维持它。

那我该如何:

  • 仅在不同的行上汇总数量,或
  • 在给定WHERE / HAVING(因此没有子查询)的情况下,计算每行的增值税税率?
  • 我可以在表格中添加额外的字段来帮助解决这个问题,但这种可能性对我没有帮助。例如:存储增值税税率并没有帮助,因为在WHERE中可能会有增值税税率的选择。

我希望这是一件非常简单的事情,我忽略了,但我现在一直在寻找几个小时无济于事......

如果有人能帮助我,那就太好了!提前谢谢!


编辑:我找到了一个解决方案,但我对此并不满意。我必须拆分WHERE,SUM SUMs和重复列......它很难以维护。

如下:

SELECT `Inv.Nr`, ArticleID, SUM(Quantity), SUM(Amount), SUM(VAT)
FROM ((`Invoice` INNER JOIN `Invoice Line` 
           ON `Invoice`.`Inv.Nr`=`Invoice Line`.`Inv.Nr`)
      INNER JOIN 
         (SELECT SUM(Amount) AS Amount, SUM(VAT) AS VAT, `Line-ID` 
             FROM ((`Invoice Line VAT` 
                  INNER JOIN `More Stuff`
                    ON .... )
             INNER JOIN ....
                   ON ..... ) 
           WHERE some-where-stuff
           GROUP BY `Line-ID`) x
         ON `Invoice Line`.ID = x.`Line-ID`)
WHERE other-where-stuff
GROUP BY .....
HAVING .....

我希望有人能找到更优雅,更简单的解决方案!

1 个答案:

答案 0 :(得分:0)

在对问题的更新中,我自己回答了这个问题。我说我希望解决方案比以下更难以维护和维护:

SELECT `Inv.Nr`, ArticleID, SUM(Quantity), SUM(Amount), SUM(VAT)
FROM ((`Invoice` INNER JOIN `Invoice Line` 
           ON `Invoice`.`Inv.Nr`=`Invoice Line`.`Inv.Nr`)
      INNER JOIN 
         (SELECT SUM(Amount) AS Amount, SUM(VAT) AS VAT, `Line-ID` 
             FROM ((`Invoice Line VAT` 
                  INNER JOIN `More Stuff`
                    ON .... )
             INNER JOIN ....
                   ON ..... ) 
           WHERE some-where-stuff
           GROUP BY `Line-ID`) x
         ON `Invoice Line`.ID = x.`Line-ID`)
WHERE other-where-stuff
GROUP BY .....
HAVING .....

事实证明,现在我正在使用这个解决方案并根据它重新描述我的所有查询,它毕竟不是那么庞大和丑陋。事实证明,它比我尝试过的其他解决方案和解决方案效果更好,也更好。因为我猜没有其他解决方案而不是我写的内容,我通过回答上面提到的答案是正确答案来解决这个问题。

事实证明,使用正确的SQL代码而不是变通方法是正确的方法,即使它最初看起来太复杂了。而且由于没有像SUM(DISTINCT ...)这样的东西可以使用不同的记录而不是值,在这种情况下,上面的代码是正确的代码。

相关问题