2011-01-16 26 views
2

問題があります。無date_dueと数ヶ月は返しません、以外mySQLは条件付きの複数のテーブルに結合しました

Invoice_Payment、請求書、クライアント、およびカレンダー

基本的に、私は、うまく機能以下のクエリを、持っている:私は4つのテーブルを持っています。 I.Eだけdate_dueの月が返されます。

注:カレンダーテーブルには、毎年の毎日の一覧が表示されます。これは、含まれている単一COLコールDATE_FIELD

データベース:http://oberto.co.nz/jInvoice.txt

予想される出力:9月が返されないか

month  total 
August  5 
September 0 
October 196 
November 205 
December 214 
January 229 

お知らせ:私の現在のクエリは、以下のようなものを返すのだろうか? LEFTはInvoice_Payments.date_paid = Calendar.date_field ONカレンダーを登録しよう:テーブルInvoice_Paymentは、私は私のようなもので、カレンダーのテーブルを結合し、左結合を使用するように持っていると思う何date_due記録

を持っていないので、それはです。しかし私は運がありません。

SELECT MONTHNAME(Invoice_Payments.date_paid) as month, SUM(Invoice_Payments.paid_amount) AS total 
FROM Invoice, Client, Invoice_Payments 
WHERE Client.registered_id = 1 
AND Client.id = Invoice.client_id 
And Invoice.id = Invoice_Payments.invoice_id 
AND date_paid IS NOT NULL 
GROUP BY YEAR(Invoice_Payments.date_paid), MONTH(Invoice_Payments.date_paid) 

何か助けに感謝します。

+0

date_dueは、請求書テーブルまたはinvoice_paymentテーブルにあります?? – shankhan

+0

「date_due」をフィルタリングするクエリのどこにも表示されません。それらの行が返されていないことは確かですか? –

+0

**なぜ、** calendarのテーブルへの参加が残っていますか? –

答えて

4

値があるかどうかに関係なく、範囲内のすべての日付の値を検索しようとしているようです。私たちはそうのような構造カレンダーテーブルを持っていると仮定すると:

Create Table Calendar 
(
    [Date] not null Primary Key 
) 

あなたのクエリは、(XとYは、あなたが調査されている範囲の開始日と終了日を表している)ので、次のようになります。

Select Year(C.Date), MonthName(C.Date) As Month 
    , Coalesce(Sum(IP.paid_amount),0) As Total 
From Calendar As C 
    Left Join (Invoice As I 
     Join Client As C1 
      On C1.id = I.client_id 
       And C.registered_id = 1 
     Join Invoice_Payments As IP 
      On IP.Invoice_id = I.Id) 
     On IP.date_paid = C.date 
Where C.Date Between X and Y 
Group By Year(C.Date), MonthName(C.Date) 

技術的には、上記のクエリはトリックを行う必要があります。しかし、別の選択肢は、あなたがコメントで尋ねどの派生テーブルを使用することです:

Select Year(C.Date), MonthName(C.Date) As Month 
    , Coalesce(Sum(Z.paid_amount),0) As Total 
From Calendar As C 
    Left Join (
       Select IP.date_paid, IP.paid_amount 
       From Invoice As I 
         Join Client As C1 
          On C1.id = I.client_id 
           And C.registered_id = 1 
         Join Invoice_Payments As IP 
          On IP.Invoice_id = I.Id 
       ) As Z 
     On Z.date_paid = C.date 
Where C.Date Between X and Y 
Group By Year(C.Date), MonthName(C.Date) 
+0

こんにちはトーマス。返信いただきありがとうございます。私は "#1066を取得する - ユニークではないテーブル/別名: 'C'" – Jarrod

+0

@ジャロッド - 修正。私はカレンダーテーブルとクライアントテーブルの両方にエイリアス "C"を使用しました。単にClientテーブルのエイリアスを変更してください。 – Thomas

+0

こんにちはトーマス、編集していただきありがとうございます。しかし、私はまだ解決できないいくつかのエラーが発生します: "'on clause'の" I.date_paid "列が不明です"。私は私の問題を理解するのに役立つ以下の図を追加しました:http://oberto.co.nz/db-sql.png – Jarrod

0

私はすべての結合を明示的に定義して読みやすくしています。

外側の簡単な例は、ヌルを有する第二のテーブルに欠落している列を埋め、最初のテーブルのすべての行を保存参加:

select column1, 
from table1 
left outer join table2 
    on table1.key = table2.key 

カレンダーテーブルを使用すると、データが失われる原因1と仮定すると、あなたの質問には次のショットがあります:

SELECT MONTHNAME(Invoice_Payments.date_paid) as month, 
     SUM(Invoice_Payments.paid_amount) 
FROM Invoice 
JOIN Client 
    ON Client.id = Invoice.client_id 
AND Client.registered_id = 1 
JOIN Invoice_Payments 
    ON Invoice_Payments.invoice_id = Invoice.id 
LEFT OUTER JOIN Calendar 
    ON Calendar.key = #yourothertable#.key  
WHERE date_paid IS NOT NULL 
GROUP BY YEAR(Invoice_Payments.date_paid), MONTH(Invoice_Payments.date_paid) 

幸運!

+0

こんにちは。返信いただきありがとうございます。私はこれが正しい軌道にあると思う。しかし、それはInvoice_Paymentテーブルでデータが失われてしまいます。私はこれを表示するために上記の質問を更新しました。 Invoice_Paymentテーブルに特定の月のレコードがない場合、その月は表示されません。そして、それは私がつかまったところです – Jarrod

+0

Hey Jarrod、あなたは今考えているかもしれませんが、Invoice_Paymentテーブルのためにデータが失われている場合は、私が書いたステートメントでその特定の結合を変更できます: 'LEFT OUTER JOIN Invoice_Payments 'カレンダーについての2行を削除する – cag

1

私は同様の問題に遭遇し、WHERE句のうち、とに非カレンダーテーブルの条件を移動することによってそれを解決してきました結合。ここに私の完全な説明を参照してください:あなたはX = YなどでTABLE1に参加左にTABLE1、テーブル2、表3から考慮する必要がありますあなたの場合はhttps://gist.github.com/1137089

...

関連する問題