web-dev-qa-db-ja.com

Redshift:文字列から動的クエリを実行する

Amazon Redshiftの文字列フィールドに保存されている動的SQLクエリを実行したいと思います。

私のバックグラウンドは主にT-SQLリレーショナルデータベースです。私はSQLステートメントを動的に作成し、変数に格納して実行していました。 Redshiftがステートメントを準備して実行できることは知っていますが、文字列フィールドに格納されているクエリを実行できるかどうか疑問に思います。

Pg_ *システムテーブルを使用して、いくつかのテーブルの統計を使用して以下のコードを動的に構築するコードがあります。すべての列/テーブル名は動的に計算されます。クエリ出力の例を次に示します。

SELECT h_article_id AS key, 'transport_parameters_weight_in_grams' AS col_name, COUNT(DISTINCT transport_parameters_weight_in_grams) AS count_value FROM dv.s_products GROUP BY h_article_id UNION ALL
SELECT h_article_id AS key, 'transport_parameters_width_in_mm' AS col_name, COUNT(DISTINCT transport_parameters_width_in_mm) AS count_value FROM dv.s_products GROUP BY h_article_id UNION ALL
SELECT h_article_id AS key, 'label_owner_info_communication_address' AS col_name, COUNT(DISTINCT label_owner_info_communication_address) AS count_value FROM dv.s_products GROUP BY h_article_id

この動的なコードを別のクエリ内に入力したいので、次のようにいくつかの統計を作成できます。

SELECT col_name, AVG(count_value*1.00) AS avg_count
FROM (
  'QUERY ABOVE'
) A
GROUP BY col_name;

これは次のようなものを出力します:

col_name                                avg_count
transport_parameters_weight_in_grams    1.00
transport_parameters_width_in_mm        1.00
label_owner_info_communication_address  0.60

これを行う自然な方法は、すべてを文字列として変数に格納し、それを実行することです。しかし、Redshiftはこれをサポートしていません。

動的SQLコードを実際に作成する別の方法はありますか?

9
anahnarciso

これは、ストアドプロシージャのサポートを追加したことで可能になりました。 "Amazon Redshiftのストアドプロシージャの概要"

たとえば、このストアドプロシージャはテーブルの行をカウントし、テーブル名と行カウントを別のテーブルに挿入します。両方のテーブル名が入力として提供されます。

CREATE PROCEDURE get_tbl_count(IN source_tbl VARCHAR, IN count_tbl VARCHAR) AS $$
BEGIN
EXECUTE 'INSERT INTO ' || quote_ident(count_tbl) 
        || ' SELECT ''' || source_tbl ||''', COUNT(*) FROM ' 
        || quote_ident(source_tbl) || ';' 
RETURN;
END;
$$ LANGUAGE plpgsql;

あなたの例では、実行するクエリを文字列として渡すことができます。

3
Joe Harris

いいえ。Redshiftで動的に構築されたSQLコードを実行する簡単な方法はありません。

MS SQL Serverの場合のように、SQL変数を定義したり、ストアドプロシージャを作成したりすることはできません。

RedshiftのPython関数 を作成できますが、Python vs.SQLでコーディングします。

"PREPARE"および "EXECUTE"ステートメントを使用して、「事前定義された」SQL クエリを実行できますが、ステートメントを実行コマンドに渡す前に、データベースの外部でステートメントを作成する必要があります。データベースの外でステートメントを作成することにより、目的に反する方法でステートメントを作成します。「好きな」プログラミング言語でステートメントを作成できます。

すでに述べたように、このSQLベースのデータベース内動的SQLは存在しません。

基本的に、アプリケーションでこのロジックを実行するか、AWS Data Pipelineなどを使用する必要があります。

3
BigDataKid

RedshiftでPostgreを使用していますが、この問題に遭遇し、解決策を見つけました。

私は自分の日付を入れて、動的クエリを作成しようとしていました。

date = dt.date(2018, 10, 30)

query = ''' select * from table where date >= ''' + str(my_date) + ''' order by date '''

ただし、この方法で入力すると、クエリは条件を完全に無視します。

ただし、パーセント記号(%)を使用すると、日付を正しく挿入できます。

上記のステートメントを記述する正しい方法は次のとおりです。

query = ''' select * from table where date >= ''' + ''' '%s' ''' % my_date + ''' order by date '''

だから、多分これは役に立つか、そうでないかもしれません。私の状況でそれが少なくとも一人の助けになることを願っています!

ご多幸を祈る。

0
spen.smith