1

私は現在、最初にWITH演算子とSELECTステートメントを使用して多くの一時テーブルを作成し、最後にすべての一時ステートメントを結合するSQLクエリを作成しています。

一時テーブルを作成するすべての SELECT ステートメントは、特定のフィルターに依存しています...そのため、クエリは何か嘘のように見えます

  WITH 

  table_1 as (
  SELECT  product_id 
          avg(price)
  FROM daily_sales 
  WHERE product_category = 1 
  AND sell_date BETWEEN TO_DATE('2012/01/07','YYYY/DD/MM') AND TO_DATE('2012/30/09','YYYY/DD/MM')
  GROUP BY ds.product_id
  ),

  table_2 as (....
 ),


SELECT FROM table_1 JOIN table_2.... 

「sell_date」(日付または文字列) の範囲と「product_category」(整数値) のさまざまな値に対してこのクエリを実行したいと考えています。

現在、これらを手動で置き換えていますが、これらのハードコードされた値を、クエリの上部に設定した変数に置き換えることを宣言できるかどうか疑問に思っています。

これは以前に尋ねられた可能性があることを理解していますが、使用している SQL の正確なバージョンと宣言している変数の型に依存する複数の解決策があるため、混乱しています。

この場合、Oracle SQL で動作し、型変数を指定できるソリューションを探しています。

4

4 に答える 4

3

クエリの実行方法によって異なります。

SQL*Plus や TOAD などの対話型クライアントを使用している場合は、置換変数を使用する必要があります。

  WITH 
      table_1 as (
      SELECT  product_id 
              avg(price)
      FROM daily_sales 
      WHERE product_category = &product_cat 
      AND sell_date BETWEEN TO_DATE('&start_date','YYYY/DD/MM') AND TO_DATE('&end_date','YYYY/DD/MM')
      GROUP BY ds.product_id
      ),

クエリを実行するたびに、これらの変数の値を指定するよう求められます。複数の場所で同じ値を使用する場合は、2 つのアンパサンド (&&product_category) を使用して変数のすべての出現箇所を宣言すると、1 回だけプロンプトが表示されます。SQL*Plus のドキュメントに追加情報があります:詳しくはこちらをご覧ください

ストアド プロシージャでクエリを実行する場合は、値をパラメータとして定義します...

procedure process_sales_details
     ( i_product_category in number
       , i_start_date in date
       , i_end_date in date )

...クエリで参照するもの(宣言する場所はどこでも)...

  WITH 
      table_1 as (
      SELECT  product_id 
              avg(price)
      FROM daily_sales 
      WHERE product_category = i_product_cat 
      AND sell_date BETWEEN i_start_date AND i_end_date
      GROUP BY ds.product_id
      ),
于 2013-06-29T09:34:13.390 に答える
2

これらをカプセル化するために、1 つ以上の共通テーブル式を追加できます。

with
  cte_sell_dates as (
    select date '2012-07-01' from_date,
           date '2012-09-30' to_date
    from dual),
  cte_products as (
    select 1 id from dual union all
    select 28 id from dual),
  ... as (
    select ...
    from   ...
    where  sell_date between (select from_date from cte_sell_dates) and
                             (select to_date   from cte_sell_dates) and
           product_id in     (select id        from cte_products  )
  ...

もちろん、サブクエリの代わりに直接結合を使用することもできます。

于 2013-06-29T12:59:43.417 に答える
2

Further to APC's answer, in SQL*Plus or SQL Developer you can also declare variables that you can assign values to in an anonymous PL/SQL block and then reference as bind variables in your plain SQL query:

variable v_product_cat number;
variable v_start_date varchar2(10);
variable v_end_date varchar2(10);

begin
    :v_product_cat := 1;
    :v_start_date := '2012/01/07';
    :v_end_date := '2012/30/09';
end;
/

WITH table_1 as (
    SELECT  product_id 
            avg(price)
    from daily_sales 
    where product_category = :v_product_cat 
    AND sell_date BETWEEN TO_DATE(:v_start_date,'YYYY/DD/MM')
        AND TO_DATE(:v_end_date,'YYYY/DD/MM')
    group by ds.product_id
)
...

Note the : before the variable name denoting a bind variable, and that the strings are not enclosed in quotes with this form. Unfortunately you can't declare a date variable, which would make this even neater.

And if you use substitution variables you can define them at the start so you aren't prompted; in this case you don't need to use the && notation either:

define v_product_cat=1
define v_start_date=2012/01/07
define v_end_date=2012/30/09

...
    where product_category = &v_product_cat 
    and sell_date between to_date('&v_start_date','YYYY/DD/MM')
        AND TO_DATE('&v_end_date','YYYY/DD/MM')
...

... which is covered in the documentation APC linked to.

于 2013-06-29T10:08:11.033 に答える