0

私は周りを見回しましたが、私のニーズを満たす解決策を見つけることができないようですので、あなたが助けてくれることを願っています。(私はMySQLに少し慣れていませんが、SQL ServerとOracleの経験が豊富です。)

いくつかのテーブルを持つデータベースがあります。

最初のテーブルは、基本情報を格納する定義テーブルであり、cp_defと呼ばれます。

cid (pkey)  status
-------------------
10001       0
10002       1

次に、cp_defテーブルのレコードごとに、対応するcp_ [cid]テーブルがあります([cid]はcp_defテーブルのcid値です)。例:

table: cp_10001

id(pkey)   code      date_issued    date_expired
-------------------------------------------------
1          ABC123    2011-06-23     2011-06-30
2          CYG124    2011-06-23     2011-06-30


table: cp_10002

id(pkey)   code      date_issued    date_expired
-------------------------------------------------
1          CAC126    2011-06-23     2011-06-30
2          VGC254    2011-06-23     2011-06-30

すべてのcp_[cid]テーブルのすべてのレコードのコードとdate_expired列の値を出力するために(シェルスクリプトとcronジョブの一部として)動的クエリを毎日実行する必要があります。ここで、date_issued値は前日の日付です。

クエリが機能しています(以下を参照)。ただし、新しいcp_ [CID]テーブルを追加するたびに、クエリの最後に別のUNIONALLステートメントを手動で追加する必要があります。

SELECT code, date_expired
FROM mydatabase.cp_10001
WHERE DATE(date_issued) = DATE_SUB(CURDATE(), INTERVAL 1 DAY);
UNION ALL
SELECT code, date_expired
FROM mydatabase.cp_10002
WHERE DATE(date_issued) = DATE_SUB(CURDATE(), INTERVAL 1 DAY);  

私の最終的な目標は、実行時に上記のクエリをプログラムで生成することです。これにより、新しいcp_ [CID]テーブルがデータベースに追加されるたびに、手動で介入する必要がなくなります。

ビューを使ってみました。ただし、テーブルを追加するには、新しいテーブルを考慮して、ビューを手動で変更する必要があるように見えました。

各cp_[CID]テーブルがcp_defテーブル(およびINFORMATION_SCHEMAテーブル)にリストされていることを考えると、動的クエリを構築するために何らかのループを実行できると考えていましたが、それを完全には理解していません。これを短くするために、動的クエリを作成するためにcp_defテーブルをループする試みの失敗を投稿しないようにします。

そのようなクエリを作成するための正しい方向に私を向けるためにあなたが提供できるどんな援助も大いにありがたいです。何か見落としていた場合は、お詫び申し上げます。私は、探しているものをさまざまなフレーズで正確に検索しようとしましたが、役に立ちませんでした。

4

3 に答える 3

0

(多くのcp _ ####ではなく)このような構造のテーブルを1つ持つことをお勧めします-

cp_properties:
id(pkey), cid(foreign key to cp_def.cid) , code      date_issued    date_expired

しかし、あなたが設計するために、このクエリを試してください-

SELECT GROUP_CONCAT(CONCAT('SELECT code, date_expired FROM mydatabase.cp_', cid, ' WHERE DATE(date_issued) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)') SEPARATOR '\r\nUNION ALL\r\n') FROM mydatabase.cp_def

このクエリは、UNION ALL句を使用してselectステートメントを生成し、次に、準備されたステートメントを使用して生成されたクエリを実行します。

編集

SELECT GROUP_CONCAT(CONCAT('SELECT code, date_expired FROM mydatabase.cp_', cid, ' WHERE DATE(date_issued) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)') SEPARATOR '\r\nUNION ALL\r\n') INTO @s FROM mydatabase.cp_def;
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
于 2011-06-24T06:59:08.517 に答える
0

まず、cp_データが別々のテーブルに分割されるのはなぜですか?データが適切に正規化されていれば、これは問題にはなりません。

簡単な解決策は、すべてのcp_テーブルの和集合のビューを作成することですが、IMEでは、mysqlはビュー/サブクエリのプッシュ述語をそれほど効率的に最適化しません。そして、あなたが発見したように、あなたはまだビューを維持する必要があります。

これは、Devartによって説明されたソリューションを使用することにつながります。これはデータの正規化に代わるものではありません。これほど効率的になることはなく、テーブルの数が増えると、パフォーマンスが急速に低下します。ただし、Devartは厄介な部分(手順から結果セットを取得する方法)をスキップしました。簡単な答えは、できないということです。ただし、一致した行を一時テーブルに挿入し、そこから行を選択することはできます。

于 2011-06-24T09:35:16.500 に答える
0

私は解決策を見つけました:

テーブルのUNIONALLクエリを@sに保存し、テーブルの組み合わせの結果を保存するビューを作成します。

Select group_concat(concat('select * from new_schema.', name ) separator '\r\nUNION 
ALL\r\n')
into @s from new_schema.tempTableName;
set @v = concat('create View view as ', @s);
PREPARE stmt FROM @v;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
于 2013-05-09T09:31:54.437 に答える