2009-05-24 14 views
1

私はこれを説明する方法が少し失われているので、私はいくつかのテーブル(+データ)の例を示し、その後私は(すべての私のテーブルの列がNULLではない)結果を与えることを試みます:高度な(?)SQL結合?

Table: Customers 

Id int primary key 
Name varchar(250) 

Table: Stats (Date, CustomerId is the primary key) 

Date (date) 
CustomerId (int) - foreign key to Customers table 
Earning (money) 

Table: Bonus 

Id int primary key 
CustomerId int - foreign key to Customers table 
Date date 
Amount money 

Table: Payments 

Id int primary key 
DateFrom date, 
DateTo date, 
CustomerId bigint - foreign key to Customers table 

Table: CampaignPayment 

Id int primary key 
PaymentId int - foreign key to payments table 
Quantity int 
UnitPrice money 

Table: BonusPayment 

Id int primary key 
PaymentId int - foreign key to payments table 
Amount money 

ここでの考え方は、それが統計表になり、毎回顧客がそれらにお金を稼ぐことになって何かをするということです。顧客はボーナステーブルに入るさまざまなボーナスを受け取ることもできます。ときどき、私は指定された期間内の統計表+ボーナステーブルからのものが一覧表示されます顧客(決済テーブル)の請求書を作成する必要があり、それはそれは表が定義されて支払いである(請求書を生成します請求書どの期間、どのような給料が支払われているのか、またその理由をキャンペーン支払いとボーナス支払い表で定義しています)。今

- 私は次の出力を得ることができるまで、これらすべてのテーブルを結合できるようにする必要があります。

CustomerId | CustomerName | PaymentId | Amount | BonusAmount | DateFrom | DateTo 

量は、合計額(SUM(数量*単価))でありますCampaignPaymentテーブル、BonusAmountは、BonusPaymentテーブルから合計された金額(SUM(Amount))です。 DateFromとDateToはPaymentsテーブルからのものです。

トリックは、その月の毎日が覆われていない指定された月内のすべての顧客のために、私は次のようなデータを持つ行をしたいということです。

CustomerId | CustomerName | NULL | (Stats.Earning - Amount Earned from possible payments within the month) | (Bonus.Amount - Amount Earned possible bonuses that is in payments within the month) | First day of month | Last day of month 

私は複雑なのもう少し必要があるかもしれませんこれらの「空の」行内の金額とボーナス金額をどのように計算するかについては論理がありますが、今のところそれは私が最初に必要とするものです。

どうすればいいですか?私は "初期"ビットをどのようにして終了するかを知っていますが、これらの "空の"行を追加するにはどうすればいいですか?私はこの問題を十分に詳しく説明し、あなたがここでそのアイデアを見ることができることを願っています。私に知らせていない限り、さらに説明しようとします。また別の方法としては月額すべての顧客のための「空の」行もあり、許容される溶液:

データベースは、MS SQL Serverが2008

EDITあります。

答えて

1

「月の毎日がカバーされていない」場合、私は(識別容易にするために、「その月の毎日」とやや曖昧なスペックを補助テーブルを作ると思いますが、AUXテーブルはあなたが意味するかどうかを助けるべきですのボーナスまたは統計情報がある場合、またはがある必要がある場合はのいずれも「対象」とみなされているかどうかにかかわらず、「カバーされていない日」が含まれているかどうか、 - これらのあいまいさは私がこの補助表を使ってSQLをスケッチしようとしない理由です;-)。その後、私はUNION "初期ビット"に "空の行"は、あなたがすでに完了する方法を知っている - ユニオンのための完璧な仕事のようです - )

+0

ありがとう私はそれを持って行くだろう - 私の唯一の懸念それをUNIONingすることは、同じ仕事を何度もやり直してしまうかもしれないということです。対象となる日付をPaymentsテーブルの範囲内に表示する必要があります(つまり、DateFrom - > DateTo、両方の日付が含まれます)。 私はこれを見ていますが、ありがとうございます:)。 – kastermester

+0

「初期ビット」と「空の行」で同じことをしているわけではないので、UNIONをお勧めします。対象となる日付を特定するには、Auxタブを選択してAuxtabをお勧めします。SELECTはAuxtab JOIN Paymentsから選択してください(DateFromとDateToを指定してください)CustomerId = whatever; UNcovered日付を特定するために、AuxtabからのSELECT adateは存在しません(SELECT * FROM支払いはDateFromとDateToとの間で指定し、CustomerId = whatever)。最適化&Cのためのバリエーション(申し訳ありませんが、コメントにスペースが足りない場合は、必要に応じて別のQをお尋ねください)。 –