2011-08-13 4 views
2

曖昧なタイトルには申し訳ありませんが、私がやりたいことはワンライナーではほとんど記述できません。MySQLでは、セミ関連のレコードに基づいてビューフィールドを計算するにはどうすればよいですか?

私は自分の財政を管理するために、MySQL 5.1.30バックエンド付きの簡単なWebアプリケーションを持っています。

id INT PRIMARY KEY, 
date DATE 

そしてbill_rowsテーブル:

id INT, 
bill INT REFERENCES bills (ID), 
cost DECIMAL(16,2), 
taxable TINYINT(1) 

そして最後に、追加のtaxes列が導入されtaxed_bill_rowsビュー、:

SELECT 
    r.id AS `id`, 
    r.bill AS `bill`, 
    r.cost AS `cost`, 
    (CASE 
     WHEN i.taxable 
      THEN floor((r.cost * 1.05 * 1.075) * 100)/100.00 - r.cost) 
     ELSE 
      0.00 
    END) AS `taxes` 
FROM bill_rows r 

1.05倍これはbillテーブルを持っています連邦税率であり、1.075は地方税率です。 (* 1.05 * 1.075は間違いではありません:地方税も連邦税に適用されます)

しかし、これらの値はもはや最新ではありません(私は実際これに非常に遅れています)。今年の1月1日からまで以降、連邦税率は1%高く、1.085までです。税率は、問題を解決するために変更

、私は新しいtax_ratesテーブルを作成しました:

ID INT, 
date DATE, 
federal DECIMAL(4,2), 
provincial DECIMAL(4,2) 

税率が変更するたびに、私はそこに新しいレコードを挿入します。

問題は、請求書のdateフィールドに基づいて、どのように関連する税率にアクセスできますか?私はちょうどLEFT JOIN tax_rates tr ON tr.date < b.dateを行うことができないので、あまりにも多くのレコードを取り戻す可能性があります。 billsテーブルに外部キーtax_ratesを追加すると、その変更が行われることがありますが、その変更はあまり価値がないようです。

答えて

1

あなたtax_ratesの表は、開始&終了を示すために、2つの日付の列を必要とします:

CREATE TABLE tax_rates (
    id INT, 
    start_date DATE, 
    end_date DATE, 
    federal_tax_rate DECIMAL(4,2), 
    provincial_tax_rate DECIMAL(4,2)) 

次に、あなたが参加するためにBETWEEN使用することができます。税率について

JOIN tax_rates tr ON tr.date BETWEEN b.start_date AND b.end_date 
+0

とすると、税率には「無期限に遠い」終了日が必要ですか? – zneak

+0

@ zneak:はい。 –

0

foregnキーが最高になります溶液。あなたがフィールドを追加することができ、すなわち、

パフォーマンスのための最高の、メンテナンスのための最高の、

他のソリューションは、より遅いと

読みにくくなりSTART_DATEとテーブル をtax_ratesすると

left join tax_rates tr on b.`date` between tr.start_date and tr.end_date 
のように参加するかしEND_DATE

この場合も、最初のレコードの開始日は0で、最後のレコードの大きい日付は

+0

あなたはパフォーマンスのために外部キーを使用しません。これはデータの完全性のためです。計算された値を格納することは、別のテーブルに結合するよりも速くなります。あなたの場合はまだ –

+0

に参加してください。そして外部キーではるかに速く(そして有効で可読な)結合してから計算に参加してください。 – Tigra

+0

計算を一度実行し、検索のために結果を格納することは、結合より常に速くなります。 –

関連する問題