4

我正在尝试创建一个查询,该查询将从我正在创建的计费系统的四个表中获取信息。我有以下表格:

表发票

InvoiceID (PK)
ClientID
Date
Status
...

表客户端

ClientID (PK)
ClientName
...

表发票项

ItemID (PK)
InvoiceID
Amount
...

餐桌付款

PaymentID (PK)
InvoiceID
Amount
...

我需要创建一个查询,我可以在其中访问 Invoice 表中的信息以及客户名称,以及与发票关联的所有发票项目和付款的总和。

我尝试了以下方法:

SELECT 
    Invoice.InvoiceID, 
    Invoice.`Date`, 
    Invoice.Terms, 
    Invoice.DateDue, 
    Invoice.Status, 
    Client.ClinicName, 
    SUM(InvoiceItem.Amount), 
    SUM(Payment.PaymentAmount)
FROM Invoice
JOIN (Client, InvoiceItem, Payment) ON
    (Client.ClientID=Invoice.ClientID AND
     InvoiceItem.InvoiceID=Invoice.InvoiceID AND 
     Payment.InvoiceID=Invoice.InvoiceID)

虽然这种方法有效,但它将 SUM() 乘以用于获得总和的记录数(即,如果有两次付款 - 800,400 - 它给了我 (800+400)*2 -- 2400)。我猜我使用联接的方式有些问题,老实说,我从来不需要对多个表使用联接,而且我总是使用 GROUP BY,但我似乎无法让它正常工作.

更糟糕的是,过去几年我一直迷失在 vb.net/MSSQL 客户端编程的世界中,所以我的 MySQL 相当粗糙。

4

4 回答 4

6

您的问题是您不能在单个查询中一次聚合两个独立的表。但是,您可以使用子查询来做到这一点。

SELECT Invoice.InvoiceID, Invoice.`Date`, Invoice.Terms, Invoice.DateDue, Invoice.Status, Client.ClinicName, InvoiceItemSum.SumOfAmount, PaymentSum.SumOfPaymentAmount
  FROM Invoice
  INNER JOIN Client ON Client.ClientID = Invoice.ClientID
  INNER JOIN (
    SELECT InvoiceID, SUM(Amount) AS SumOfAmount
      FROM InvoiceItem
      GROUP BY InvoiceID
  ) InvoiceItemSum ON InvoiceItemSum.InvoiceID = Invoice.InvoiceID
  INNER JOIN (
    SELECT InvoiceID, SUM(PaymentAmount) AS SumOfPaymentAmount
    FROM Payment
    GROUP BY InvoiceID
  ) PaymentSum ON PaymentSum.InvoiceID = Invoice.InvoiceID
于 2012-08-31T00:02:02.113 回答
0

这里试试这个

SELECT  a.InvoiceID,
        a.`Date`,
        a.Terms,
        a.DateDue,
        a.Status,
        b.ClinicName,
        SUM(c.Amount),
        SUM(d.PaymentAmount)
FROM    Invoice a
            INNER JOIN Client b
                on a.ClientID = b.ClientID
            INNER JOIN InvoiceItem c
                ON c.InvoiceID = a.InvoiceID
            INNER JOIN JOIN Payment d
                ON d.InvoiceID = a.InvoiceID
GROUP BY    a.InvoiceID,
            a.`Date`,
            a.Terms,
            a.DateDue,
            a.Status,
            b.ClinicName

你能详细说明一下吗?

它将 SUM() 乘以用于获得总和的记录数(即,如果有两次付款 - 800,400 - 它给了我 (800+400)*2 -- 2400)

于 2012-08-31T00:01:28.817 回答
0

尝试这个:

SELECT
    Invoice.InvoiceID,
    Invoice.`Date`,
    Invoice.Terms,
    Invoice.DateDue,
    Invoice.Status,
    Client.ClinicName,
    SUM(InvoiceItem.Amount),
    SUM(Payment.PaymentAmount)
FROM Invoice 
JOIN Client ON Client.ClientID=Invoice.ClientID
JOIN InvoiceItem ON InvoiceItem.InvoiceID=Invoice.InvoiceID
JOIN Payment ON Payment.InvoiceID=Invoice.InvoiceID
group by 1,2,3,4,5,6;

我对您的查询做了两件事:

  1. 为每个子表创建单独的连接
  2. 添加了 a group by,否则总和将无法正常工作(仅供参考,在所有其他数据库中,省略 group by 实际上会导致语法错误)
于 2012-08-30T23:58:28.137 回答
0

你也可以通过“CROSS APPLY”来实现它

SELECT Invoice.InvoiceID, Invoice.`Date`, Invoice.Terms, Invoice.DateDue, Invoice.Status, Client.ClinicName, InvoiceItemSum.SumOfAmount, PaymentSum.SumOfPaymentAmount
  FROM Invoice
  INNER JOIN Client ON Client.ClientID = Invoice.ClientID
  CROSS APPLY ( SELECT ISNULL(SUM(Amount),0) AS SumOfAmount 
                                  FROM   InvoiceItem 
                                  WHERE  InvoiceID = Invoice.InvoiceID
                                ) InvoiceItemSum 
  CROSS APPLY ( SELECT ISNULL(SUM(PaymentAmount),0) AS SumOfPaymentAmount 
                                  FROM   Payment 
                                  WHERE  InvoiceID = Invoice.InvoiceID
                                ) PaymentSum 
于 2016-05-25T13:59:14.687 回答