あなたが何を求めているのかは実際には完全には明らかではありませんが、答えを試みさせてください。
まず、テーブルとサンプル データを作成しましょう。
SQL フィドル
PostgreSQL 9.1.9 スキーマのセットアップ:
CREATE TABLE Change
("id" int, "action_id" int, "field_id" int, "old_value" varchar(10), "new_value" varchar(10))
;
INSERT INTO Change
("id", "action_id", "field_id", "old_value", "new_value")
VALUES
(39, 15, 14,'', 'testPool'),
(40, 15, 15,'', 'testSystem'),
(41, 15, 16,'', '61019')
;
CREATE TABLE Action
("id" int, "description" varchar(12), "audited_table" varchar(11), "audited_row" int, "audited_type" varchar(6))
;
INSERT INTO Action
("id", "description", "audited_table", "audited_row", "audited_type")
VALUES
(15, 'Added system', 'systemtable', 61019, 'insert')
;
CREATE TABLE Field
("id" int, "audited_table" varchar(11), "name" varchar(13))
;
INSERT INTO Field
("id", "audited_table", "name")
VALUES
(14, 'systemtable', 'pool'),
(15, 'systemtable', 'storagesystem'),
(15, 'systemtable', 'id')
;
あなたの質問がテーブルに参加する方法に関するものである場合、答えはかなり簡単です。
クエリ 1 :
SELECT C.id,
A.description,
F.audited_table,
A.audited_row,
A.audited_type,
F.name AS field_name,
C.new_value
FROM Change AS C
JOIN Action AS A
ON C.action_id = A.id
JOIN Field AS F
ON C.field_id = F.id;
結果:
| ID | DESCRIPTION | AUDITED_TABLE | AUDITED_ROW | AUDITED_TYPE | FIELD_NAME | NEW_VALUE |
|----|--------------|---------------|-------------|--------------|---------------|------------|
| 39 | Added system | systemtable | 61019 | insert | pool | testPool |
| 40 | Added system | systemtable | 61019 | insert | storagesystem | testSystem |
| 40 | Added system | systemtable | 61019 | insert | id | testSystem |
結合の詳細については、次のブログ シリーズを参照してください
。 .
複数の行を 1 つに変換しようとしている場合は、ピボットを探しています。MAX()
基本的に行をグループ化し、との組み合わせを使用しCASE
て単一の値を選択することで、ピボットを実行できます。あなたの質問の問題は、フィールド「field1」と「field2」の違いを指定していないことです。これを解決するために、関数を使用して field_id の順にフィールドに番号を付けましたROW_NUMBER()
。これにより、最初のフィールドは、field_id が最小のフィールドになります。ピボットは次のようになります。
クエリ 2 :
SELECT action_id,
audited_table,
MAX(CASE WHEN field_number = 1 THEN name END) AS f1_name,
MAX(CASE WHEN field_number = 1 THEN new_value END) AS f1_new_value,
MAX(CASE WHEN field_number = 2 THEN name END) AS f2_name,
MAX(CASE WHEN field_number = 2 THEN new_value END) AS f2_new_value
FROM(
SELECT *,ROW_NUMBER()OVER(PARTITION BY C.action_id, F.audited_table ORDER BY F.id) field_number
FROM Change AS C
JOIN Field AS F
ON C.field_id = F.id
)X
GROUP BY action_id, audited_table;
結果:
| ACTION_ID | AUDITED_TABLE | F1_NAME | F1_NEW_VALUE | F2_NAME | F2_NEW_VALUE |
|-----------|---------------|---------|--------------|---------|--------------|
| 15 | systemtable | pool | testPool | id | testSystem |
クエリ 2 は、Field テーブルと Change テーブルの情報を取得するだけです。アクション情報も取得するには、別の結合を追加する必要があります。
クエリ 3 :
SELECT A.id,
A.description,
X2.audited_table,
A.audited_row,
A.audited_type,
X2.f1_name,
X2.f1_new_value,
X2.f2_name,
X2.f2_new_value
FROM Action AS A
JOIN (
SELECT action_id,
audited_table,
MAX(CASE WHEN field_number = 1 THEN name END) AS f1_name,
MAX(CASE WHEN field_number = 1 THEN new_value END) AS f1_new_value,
MAX(CASE WHEN field_number = 2 THEN name END) AS f2_name,
MAX(CASE WHEN field_number = 2 THEN new_value END) AS f2_new_value
FROM(
SELECT *,ROW_NUMBER()OVER(PARTITION BY C.action_id, F.audited_table ORDER BY F.id) field_number
FROM Change AS C
JOIN Field AS F
ON C.field_id = F.id
)X1
GROUP BY action_id, audited_table
)X2
ON A.id = X2.action_id
結果:
| ID | DESCRIPTION | AUDITED_TABLE | AUDITED_ROW | AUDITED_TYPE | F1_NAME | F1_NEW_VALUE | F2_NAME | F2_NEW_VALUE |
|----|--------------|---------------|-------------|--------------|---------|--------------|---------|--------------|
| 15 | Added system | systemtable | 61019 | insert | pool | testPool | id | testSystem |
これがあなたの質問に答えることを願っています。