1

私はinvoicesテーブルを持っています。各請求書には多数のinvoice_itemsand transactions(または、必要に応じて「支払い」) があります。請求書ごとに、支払額 (つまり、そのトランザクションの金額の合計) と合計金額 (つまり、アイテムの金額の合計) を計算したいと考えています。

次のクエリを作成しました。

SELECT 
  invoices.*,
  SUM(transactions.amount_cents) AS amount_paid,
  SUM(invoice_items.quantity * invoice_items.price_cents) AS total
FROM invoices
RIGHT JOIN transactions 
  ON invoices.id = transactions.invoice_id
RIGHT JOIN invoice_items 
  ON invoices.id = invoice_items.invoice_id

ただし、total何らかの理由で、フィールドの値にトランザクション数が乗算されます (たとえば、合計金額が20でトランザクションが2totalの請求書がある場合、フィールドは40になります)。

クエリからトランザクションへの参照をすべて削除すると、次のようになります。

SELECT 
  invoices.*,
  SUM(invoice_items.quantity * invoice_items.price_cents) AS total
FROM invoices
RIGHT JOIN invoice_items 
  ON invoices.id = invoice_items.invoice_id

totalフィールドは正しく返されます...

私はこの問題の専門家ではないので、おそらく非常にばかげたことをしているのでしょう。JOIN のさまざまな組み合わせを既に試しましたが、結果はありません。

ヒントはありますか?

編集:セミファイナルソリューション

未払いの請求書を取得しようとしていたので、最後のクエリは次のとおりです。

SELECT 
  invoices.*,
  SUM(invoice_items.quantity * invoice_items.price_cents) AS total,
t.amount_paid
FROM invoices
LEFT JOIN invoice_items 
  ON invoice_items.invoice_id = invoices.id
LEFT JOIN (
  SELECT 
    invoice_id, 
    SUM(transactions.amount_cents) AS amount_paid
  FROM transactions 
  GROUP BY invoice_id
) t
  ON invoices.id = t.invoice_id
GROUP BY invoices.id
HAVING amount_paid >= total;

編集:参加する必要がないことに気付いた後...

関連するデータを取得する必要はありません。請求書が支払われたか未払いかを知りたいだけです。だから私は単純な場所を使用することになりました:

SELECT `invoices`.* 
FROM `invoices` 
WHERE (
  (
    SELECT COALESCE(SUM(t.amount_cents), 0)
    FROM transactions t 
    WHERE t.invoice_id = invoices.id
  )
  >=
  (
    SELECT COALESCE(SUM(i.quantity * i.price_cents), 0)
    FROM invoice_items i
    WHERE i.invoice_id = invoices.id
  )
)

しかし、助けてくれたみんなに感謝します。

4

2 に答える 2

2

サブクエリを使用して、invoice_id ごとに最大 1 行までトランザクションを集計して、余分な行が発生しないようにすることができます。ボリュームによっては、サブクエリを一時テーブルにハイブし、一時テーブルを参照したい場合があります。

SELECT 
  invoices.*,
  SUM(invoice_items.quantity * invoice_items.price_cents) AS total,
t.Amount_Paid
FROM invoices
LEFT JOIN invoice_items 
  ON invoice_items.invoice_id = invoices.id
LEFT JOIN (select invoice_id, SUM(transactions.amount_cents) as Amount_Paid from
transactions group by invoice_id) t
  ON invoices.id = t.invoice_id
GROUP BY invoices.id
于 2013-06-10T13:54:02.107 に答える
2

重複はデカルトの結果に基づいています...ご指摘のとおり、1つの請求書には複数の取引があるため、存在するたびに取引額がカウントされます。請求書IDでグループ化された独自の合計を取得するには、おそらくそれぞれのテーブルからのサブクエリが必要です...

SELECT 
      invoices.*,
      Payments.Amount_Paid,
      Items.Items_Total
   FROM 
      invoices
         JOIN ( select
                      T.Invoice_ID, 
                      sum( T.amount_cents ) amount_paid
                   from 
                      transactions T
                   group by
                      T.Invoice_ID ) Payments
            on Invoices.id = Payments.Invoice_ID
         JOIN ( select
                      II.Invoice_ID, 
                      sum( II.quantity * II.price_cents) AS Items_total
                   from 
                      Invoice_Items II
                   group by
                      II.Invoice_ID ) Items
            on Invoices.id = Items.Invoice_ID
于 2013-06-10T13:58:52.143 に答える