2016-10-25 14 views
1

私は販売の瞬間に購入価格を取得しようとしています。私のテーブルには同じ商品の購入価格が異なります。販売時点での購入価格を取得

購入価格は2つの日付で定義されています。有効期限の開始日と有効期限終了日はそれぞれDATE_DEB_VALIDとDATE_FIN_VALIDです。

私が販売時点(FLIGHT_DATE)で獲得した数を知りたいのであれば、同じ期間に購入価格を知る必要があります。

TB_DW_VAB_SALES  

- ID_TEC_SALES 
- TRANSACTION_NUMBER 
- CARRIER_CODE 
- MASTER_FLIGHT_NUMBER 
- FLIGHT_NUMBER 
- FLIGHT_DATE 
- FLIGHT_CITY_DEP 
- FLIGHT_CITY_ARR 
- PRODUCT_CODE 
- QUANTITY 
- UNIT_SALES_PRICE 
- PROMOTION_CODE 
- CREW_PRICE 
- COMPLEMENTARY 
- SALES_TYPE 
- DATE_CHGT 

TB_DW_VAB_PURCHASE 

    - PRODUCT_CODE 
    - PRODUCT_CODE_GUEST 
    - LIB_PRODUCT 
    - PRICE DATE_DEB_VALID 
    - DATE_FIN_VALID 
    - DATE_CHGT 

マイリクエスト: 私のフライトの日付は "DATE_DEB_VALID" と "DATE_FIN_VALID"

の間で二つのテーブルでなければなりません

SELECT (TB_DW_VAB_PURCHASE.PRODUCT_CODE),PRICE 
     FROM TB_DW_VAB_PURCHASE,TB_DW_VAB_SALES 
     WHERE FLIGHT_DATE BETWEEN DATE_DEB_VALID AND DATE_FIN_VALID AND to_char(FLIGHT_DATE,'YYYY')= '2016' OR to_char(FLIGHT_DATE,'YYYY')= '2015' 
     GROUP BY TB_DW_VAB_PURCHASE.PRODUCT_CODE, PRICE 

ここでは、(情報のため)全体の要求を持っています:

SELECT to_char(DATE_VENTE,'MM/YYYY'),sum(MARGE_TOTALE) FROM (
    SELECT 
      CTE1.CA AS CHIFFRE_AFFAIRE_TOTAL, 
      CTE2.PRICE AS COUT_UNITAIRE, 
      CTE1.FLIGHT_DATE as DATE_VENTE, 
      CTE1.QTE*CTE2.PRICE AS COUT_ACHAT, 
      (CTE1.CA-CTE1.QTE*CTE2.PRICE) AS MARGE, 
      sum((CTE1.CA-CTE1.QTE*CTE2.PRICE)) as MARGE_TOTALE 
    FROM (
     SELECT PRODUCT_CODE, 
     sum(QUANTITY*UNIT_SALES_PRICE) AS CA, 
     FLIGHT_DATE, 
     sum(QUANTITY) as QTE 
     FROM TB_DW_VAB_SALES 
     where SALES_TYPE = 'SALES' and to_char(FLIGHT_DATE,'YYYY')= '2015' OR to_char(FLIGHT_DATE,'YYYY')= '2016' 
     group by to_char(FLIGHT_DATE,'MM'),FLIGHT_DATE,PRODUCT_CODE 
     ORDER BY to_char(FLIGHT_DATE,'MM') ASC 
    )CTE1 

inner join 
    (
     SELECT (TB_DW_VAB_PURCHASE.PRODUCT_CODE),PRICE 
     FROM TB_DW_VAB_PURCHASE,TB_DW_VAB_SALES 
     WHERE FLIGHT_DATE BETWEEN DATE_DEB_VALID AND DATE_FIN_VALID AND to_char(FLIGHT_DATE,'YYYY')= '2016' OR to_char(FLIGHT_DATE,'YYYY')= '2015' 
     GROUP BY TB_DW_VAB_PURCHASE.PRODUCT_CODE, PRICE 
    ) CTE2 
on CTE1.PRODUCT_CODE=CTE2.PRODUCT_CODE 
group by to_char(FLIGHT_DATE,'MM'), FLIGHT_DATE, 'MM', CTE1.FLIGHT_DATE, (CTE1.CA-CTE1.QTE*CTE2.PRICE), 
CTE1.CA, CTE1.QTE, CTE2.PRICE, CTE1.QTE*CTE2.PRICE 

) group by to_char(DATE_VENTE,'MM/YYYY') ORDER BY to_char(DATE_VENTE,'MM/YYYY') ASC; 

ありがとうございます!

+0

SQL Serverタグを削除しました。コードは明らかにOracleです。 –

+0

テーブル構造(DDL)、サンプルデータ、および期待される結果が役立ちます。あなたは正確に何を苦労していますか?エラーが出るのですか、結果だけではありませんか? –

+0

エラーなし、無限ループのみ – devicz

答えて

2

、あなたは、あなたのCTE2サブクエリでクロス参加していますフライト/有効日が、すべての商品に適用されますそれはあなたが意図したものではありません。

インラインビュー(CTE1/2という名前は通常は共通のテーブル式やサブクエリのファクタリングを参照するため、これはちょっと混乱しています)を計算しているようですが、後で計算するために使用します中間のステップまたは値が必要であると考えてください。

それは(あなたのクエリのようなものに単純化することができるように*になります。私はそれを正しく解釈されてきた確認できないサンプルデータや予想される結果なし

もちろん
select to_char(trunc(s.flight_date, 'MM'),'MM/YYYY') as mois_du_sales, 
    sum(s.quantity*(s.unit_sales_price - p.price)) as marge_totale 
from tb_dw_vab_sales s 
join tb_dw_vab_purchase p 
on p.product_code = s.product_code 
and s.flight_date between p.date_deb_valid and p.date_fin_valid 
where s.sales_type = 'SALES' 
and s.flight_date >= date '2015-01-01' 
and s.flight_date < date '2017-01-01' 
group by trunc(s.flight_date, 'MM') 
order by trunc(s.flight_date, 'MM') asc; 

また、解決しない場合があります。すべてのパフォーマンス上の問題 - テーブルやインデックス、実行プランを見て、実際に何が行われているかを確認する必要があります。大量のデータと便利なパーティションキー(sales年)

to_char(FLIGHT_DATE,'YYYY')= '2015'のようなフィルタを使用すると、その列のすべての値が強制的に(または少なくともtホースがsales_typeと一致していれば、それはインデックス化され、十分に選択的です)、文字列に変換されてから両方の年を別々にチェックしているように固定値と比較され、flight_dateのインデックスは使用されなくなります。長年にわたるデータがまだ使用するのに十分な選択肢でない場合や、オプティマイザが依然としてフル・テーブル・スキャンを選択している場合を除き、日付範囲を使用すると索引を使用できます。しかし、あなたが潜在的にやっていた2つのテーブルではなく、それぞれのテーブルの1つだけです。

+0

それは動作します!大いに感謝する !! 今、すべてのリクエストを最適化するようになりました。良い一日を ! – devicz

2

私はちょうどあなたがちょうどあなたの基本的な代数をforgottedまで、あなたの最初のクエリを修正(AND ORよりも優先順位を持っている)になります。

SELECT (TB_DW_VAB_PURCHASE.PRODUCT_CODE),PRICE 
FROM TB_DW_VAB_PURCHASE,TB_DW_VAB_SALES 
WHERE FLIGHT_DATE BETWEEN DATE_DEB_VALID AND DATE_FIN_VALID AND 
(to_char(FLIGHT_DATE,'YYYY')= '2016' OR to_char(FLIGHT_DATE,'YYYY')= '2015') 
GROUP BY TB_DW_VAB_PURCHASE.PRODUCT_CODE, PRICE 

は今、あなたは、正規化を使用した場合の参加、また、あなたが持っていたことを見ているだろう最後に、PRODUCT_CODE上句に参加忘れ: - 以外によるNemerosがすでに指摘したように、あなたが一緒に売買をリンクされていないよう

SELECT PUR.PRODUCT_CODE, PRICE 
FROM TB_DW_VAB_PURCHASE PUR 
inner join TB_DW_VAB_SALES SAL ON PUR.PRODUCT_CODE = PUR.PRODUCT_CODE 
    AND FLIGHT_DATE BETWEEN DATE_DEB_VALID AND DATE_FIN_VALID 
WHERE to_char(FLIGHT_DATE,'YYYY')= '2016' OR to_char(FLIGHT_DATE,'YYYY')= '2015' 
GROUP BY PUR.PRODUCT_CODE, PRICE 
+0

同じ問題、無限ループ.. – devicz

+0

あなたが説明計画を提供し、それが機能していない場合は、 – Nemeros

関連する問題