1

私は3つのテーブルを持っています

請求書: ID、クライアント

サービス: invice_id、価格

支払い: 請求書 ID、金額

請求書ごとに、サービス価格が amountDue であり、支払い額が amountPaid であるすべての請求書を選択したいと考えています。

たとえば、次の行があるとします。

請求書

id = 1, client = 232
id = 2, client = 535

サービス

invoice_id = 1, price = 5.00
invoice_id = 1, price = 10.00
invoice_id = 2, price = 20.00

支払い

invoice_id = 1, amount = 7.00
invoice_id = 2, amount = 12.00
invoice_id = 2, amount = 8.00

すべての請求書行の結果のクエリを次のようにしたい:

請求書

id = 1, client = 232, amountDue = 15.00, amountPaid = 7.00
id = 2, client = 535, amountDue = 20.00, amountPaid = 20.00

次のようなクエリがありました。

SELECT invoices.*, 
sum(services.price) AS amountDue, 
sum(payments.amount) AS amountPaid 
FROM invoices 
LEFT JOIN services ON services.invoice = invoices.id 
LEFT JOIN payments ON invoices.id = payments.invoice 
GROUP BY invoices.id

しかし、結果の amountPaid は、各請求書のサービス数で乗算されていました。

1 つのクエリですべてのデータを取得する方法はありますか?

4

1 に答える 1

1

それぞれの結合で返される行数が異なる 2 つの子テーブルがあります。グループ化/合計なしでクエリを実行すると、次のようになります。

+------+-----------+-------+-----------+--------+
| id   | serviceid | price | paymentid | amount |
+------+-----------+-------+-----------+--------+
|    1 |         1 |  5.00 |         1 |   7.00 |
|    1 |         1 | 10.00 |         1 |   7.00 |
|    2 |         2 | 20.00 |         2 |  12.00 |
|    2 |         2 | 20.00 |         2 |   8.00 |
+------+-----------+-------+-----------+--------+

請求書 #1 の支払い金額 $7 と、請求書 #2 のサービス価格が重複していることに注目してください。MySQL は、行数の少ないテーブルから値を複製することにより、クエリ構造が生成する「穴」を埋めようとしています。

この種のクエリを機能させるには、相互に関連するサブクエリを使用する必要があります。これにより、各サブクエリが、他のテーブルの行数制限に縛られることなく独自の合計を実行できるようになります。

select invoices.id,
   (select sum(price) from services where services.iid = invoices.id ) AS service_price,
   (select sum(amount) from payments where payments.iid = invoices.id) AS payment_amount
FROM invoices;

生産する

+------+---------------+----------------+
| id   | service_price | payment_amount |
+------+---------------+----------------+
|    1 |         15.00 |           7.00 |
|    2 |         20.00 |          20.00 |
+------+---------------+----------------+
于 2013-02-16T23:47:42.087 に答える