これは、使用しているPostgreSQLのバージョンによっていくつかの方法があります。私はここで複数のサブクエリでそれを解決します。
:Properties
テーブルでは、プロパティの役割を指定しますが、それにはComponentProperties
もあります。私はあなたが複数の場所に同じデータを持つことを望んでいないと仮定しているので、ここではソリューションではComponentProperties
のrole_idは存在しないと仮定します。
最初の問題は、key:value-pairsのリストをどのように検索して検索できるようにするかです。
CREATE TEMP TABLE key_value_role AS (
key text,
value text,
role text
);
そして、そのテーブル内のすべての値を挿入します。
一つの方法は、(一時的な)表を作成することです。
INSERT INTO key_value_role VALUES
('Key 1', 'Value 1', 'Role 1'),
('Key 2', 'Value 2', 'Role 1'),
('Key 2', 'Value 3', 'Role 1');
一時テーブルであっても、すばやく乱雑になります。幸いVALUES
は、スタンドアロンで使用することができます。
SELECT column1 as key, column2 as value, column3 as role
FROM (
VALUES
('Key 1', 'Value 1', 'Role 1'),
('Key 2', 'Value 2', 'Role 1'),
('Key 2', 'Value 3', 'Role 1')
) AS kvr
あなたは> = 9.3あなたがシリアライズされたJSONの文字列としてデータを送信し、json_each_textとキーを反復処理することができますPostgreSQLの使用している場合:
SELECT *, 'Role 1'::text as role
FROM json_each_text('{"Key 1":"Value 1", "Key 2":"Value 2"}')
上記の例ではリテラル文字列を使用していますが、パラメータ化されたクエリを使用し、プログラムでJSON-serialization-stringを作成すると仮定します。
上記の方法の制限は、指定されたキーには1つの値しか持たないということです。おそらくそれで十分でしょうが、私は、各キーの複数の値を検索できる柔軟なソリューションを求めていました。
Postgresql> = 9.3にはjson_populate_recordsetという別の機能がありますが、基本タイプが必要です。基本型は、既存のテーブルかもしれないが、あなたはまた、使用するタイプを作成することができますタイプが指定されている場合
CREATE TYPE key_value_role as(
key text,
value text,
role text
);
、json_populate_recordset
を使用することができます。
SELECT *
FROM json_populate_recordset(null::key_value_role,'[{"key":"Key 1", "value":"Value 1", "role":"Role 1"},{"key":"Key 2", "value":"Value 2", "role":"Role 1"}, {"key":"Key 2", "value":"Value 3", "role":"Role 1"}]')
出力例:
を
key | value | role
--------+------------+----------
"Key 1" | "Value 1" | "Role 1"
"Key 2" | "Value 2" | "Role 1"
"Key 2" | "Value 3" | "Role 1"
これで、各キーに複数の値を設定し、同じクエリで異なる役割を検索することができます。
次の問題は、名前をidsに変換することです。あなたはあなたのIDのタイプを指定していません。私は整数を仮定した。
SELECT
Keys.id as key_id, Values.id as value_id, PropertyRoles.id as role_id,
Keys.name as key_name, Values.name as value_name, PropertyRoles.name as role_name
FROM list
JOIN Keys ON (list.key = Keys.name)
JOIN Values ON (list.value = Values.name)
JOIN PropertyRoles ON (list.role = PropertyRoles.name)
出力例:テーブルと
key_id | value_id | role_id | key_name | value_name | role_name
--------+----------+---------+----------+------------+-----------
1 | 1 | 1 | "Key 1" | "Value 1" | "Role 1"
2 | 2 | 1 | "Key 2" | "Value 2" | "Role 1"
2 | 3 | 1 | "Key 2" | "Value 3" | "Role 1"
は、上記の方法で作成したリストは、その後、IDSに名前の変換は次のように行うことができる、
list
と呼ばれているものとします上記のプロパティに参加することができます:
SELECT Properties.id as property_id, Properties.name as property_name, kvr.*
FROM Properties
JOIN (
-- previous query here
) AS kvr ON (Properties.key_id = kvr.key_id AND Properties.value_id = kvr.value_id AND Properties.role_id = kvr.role_id)
出力例:
property_id | property_name | key_id | value_id | role_id | key_name | value_name | role_name
-------------+--------------------+--------+----------+---------+----------+------------+-----------
1 | "Property 01 k1v1r1" | 1 | 1 | 1 | "Key 1" | "Value 1" | "Role 1"
13 | "Property 13 k2v2r1" | 2 | 2 | 1 | "Key 2" | "Value 2" | "Role 1"
16 | "Property 16 k2v3r1" | 2 | 3 | 1 | "Key 2" | "Value 3" | "Role 1"
そして、上記の表には、今ComponentPropertiesと結合することができます。
SELECT ComponentProperties.id as ComponentProperties_id, ComponentProperties.component_id, pkvr.*
FROM ComponentProperties
JOIN (
-- previous query here
) AS pkvr ON (ComponentProperties.property_id = pkvr.property_id)
出力例:
componentproperties_id | component_id | property_id | property_name | key_id | value_id | role_id | key_name | value_name | role_name
-----------------------+--------------+-------------+--------------------+--------+----------+---------+----------+------------+-----------
1 | 1 | 1 | "Property 01 k1v1r1" | 1 | 1 | 1 | "Key 1" | "Value 1" | "Role 1"
2 | 1 | 13 | "Property 13 k2v2r1" | 2 | 2 | 1 | "Key 2" | "Value 2" | "Role 1"
3 | 1 | 16 | "Property 16 k2v3r1" | 2 | 3 | 1 | "Key 2" | "Value 3" | "Role 1"
4 | 2 | 1 | "Property 01 k1v1r1" | 1 | 1 | 1 | "Key 1" | "Value 1" | "Role 1"
7 | 3 | 16 | "Property 16 k2v3r1" | 2 | 3 | 1 | "Key 2" | "Value 3" | "Role 1"
9 | 4 | 13 | "Property 13 k2v2r1" | 2 | 2 | 1 | "Key 2" | "Value 2" | "Role 1"
そして最後に、コンポーネントとそれに参加する:
SELECT Components.name as component_name, Components.type as component_type, cpkvr.*
FROM Components
JOIN (
-- previous query here
) AS cpkvr ON (Components.id = cpkvr.component_id)
出力例:
component_name | component_type | componentproperties_id | component_id | property_id | property_name | key_id | value_id | role_id | key_name | value_name | role_name
----------------+----------------+------------------------+--------------+-------------+--------------------+--------+----------+---------+----------+------------+-----------
"Component 1" | "Component type" | 1 | 1 | 1 | "Property 01 k1v1r1" | 1 | 1 | 1 | "Key 1" | "Value 1" | "Role 1"
"Component 1" | "Component type" | 2 | 1 | 13 | "Property 13 k2v2r1" | 2 | 2 | 1 | "Key 2" | "Value 2" | "Role 1"
"Component 1" | "Component type" | 3 | 1 | 16 | "Property 16 k2v3r1" | 2 | 3 | 1 | "Key 2" | "Value 3" | "Role 1"
"Component 2" | "Component type" | 4 | 2 | 1 | "Property 01 k1v1r1" | 1 | 1 | 1 | "Key 1" | "Value 1" | "Role 1"
"Component 3" | "Component type" | 7 | 3 | 16 | "Property 16 k2v3r1" | 2 | 3 | 1 | "Key 2" | "Value 3" | "Role 1"
"Component 4" | "Component type" | 9 | 4 | 13 | "Property 13 k2v2r1" | 2 | 2 | 1 | "Key 2" | "Value 2" | "Role 1"
これはjson_populate_recordsetを使用して、クエリ全体です:
-- Get components from matching properties
SELECT Components.name as component_name, Components.type as component_type, cpkvr.*
FROM Components
JOIN (
-- Get component id from matching properties
SELECT ComponentProperties.id as ComponentProperties_id, ComponentProperties.component_id, pkvr.*
FROM ComponentProperties
JOIN (
-- Get propety id and name of matching values
SELECT Properties.id as property_id, Properties.name as property_name, kvr.*
FROM Properties
JOIN (
-- Convert key, value and role names to id
SELECT
Keys.id as key_id, Values.id as value_id, PropertyRoles.id as role_id,
Keys.name as key_name, Values.name as value_name, PropertyRoles.name as role_name
FROM
json_populate_recordset(null::key_value_role,'[{"key":"Key 1", "value":"Value 1", "role":"Role 1"},{"key":"Key 2", "value":"Value 2", "role":"Role 1"}]')
AS list
JOIN Keys ON (list.key = Keys.name)
JOIN Values ON (list.value = Values.name)
JOIN PropertyRoles ON (list.role = PropertyRoles.name)
) AS kvr ON (Properties.key_id = kvr.key_id AND Properties.value_id = kvr.value_id AND Properties.role_id = kvr.role_id)
) AS pkvr ON (ComponentProperties.property_id = pkvr.property_id)
) AS cpkvr ON (Components.id = cpkvr.component_id)
ORDER BY component_name, property_name
そして、ここでは、私が使用したテストデータである:
CREATE TYPE key_value_role as(
key text,
value text,
role text
);
create table Keys(
id integer unique primary key,
name text unique
);
create table Values(
id integer unique primary key,
name text unique
);
create table PropertyRoles(
id integer unique primary key,
name text unique
);
create table Properties(
id integer unique primary key,
name text,
key_id integer references Keys,
value_id integer references Values,
role_id integer references PropertyRoles
);
create table Components(
id integer unique primary key,
name text unique,
type text
);
create table ComponentProperties(
id integer unique primary key,
component_id integer references Components,
property_id integer references Properties,
unique (component_id, property_id)
);
INSERT INTO Keys values
(1, 'Key 1'),
(2, 'Key 2'),
(3, 'Key 3');
INSERT INTO Values values
(1, 'Value 1'),
(2, 'Value 2'),
(3, 'Value 3');
INSERT INTO PropertyRoles values
(1, 'Role 1'),
(2, 'Role 2'),
(3, 'Role 3');
INSERT INTO Properties values
(1, 'Property 01 k1v1r1', 1, 1, 1),
(2, 'Property 02 k1v1r2', 1, 1, 2),
(3, 'Property 03 k1v1r3', 1, 1, 3),
(4, 'Property 04 k1v2r1', 1, 2, 1),
(5, 'Property 05 k1v2r2', 1, 2, 2),
(6, 'Property 06 k1v2r3', 1, 2, 3),
(7, 'Property 07 k1v3r1', 1, 3, 1),
(8, 'Property 08 k1v3r2', 1, 3, 2),
(9, 'Property 09 k1v3r3', 1, 3, 3),
(10, 'Property 10 k2v1r1', 2, 1, 1),
(11, 'Property 11 k2v1r2', 2, 1, 2),
(12, 'Property 12 k2v1r3', 2, 1, 3),
(13, 'Property 13 k2v2r1', 2, 2, 1),
(14, 'Property 14 k2v2r2', 2, 2, 2),
(15, 'Property 15 k2v2r3', 2, 2, 3),
(16, 'Property 16 k2v3r1', 2, 3, 1),
(17, 'Property 17 k2v3r2', 2, 3, 2),
(18, 'Property 18 k2v3r3', 2, 3, 3),
(19, 'Property 19 k3v1r1', 3, 1, 1),
(20, 'Property 20 k3v1r2', 3, 1, 2),
(21, 'Property 20 k3v1r3', 3, 1, 3),
(22, 'Property 20 k3v2r1', 3, 2, 1),
(23, 'Property 20 k3v2r2', 3, 2, 2),
(24, 'Property 20 k3v2r3', 3, 2, 3),
(25, 'Property 20 k3v3r1', 3, 3, 1),
(26, 'Property 20 k3v3r2', 3, 3, 2),
(27, 'Property 20 k3v3r3', 3, 3, 3);
INSERT INTO Components values
(1, 'Component 1', 'Component type'),
(2, 'Component 2', 'Component type'),
(3, 'Component 3', 'Component type'),
(4, 'Component 4', 'Component type');
INSERT INTO ComponentProperties values
(1, 1, 1),
(2, 1, 3),
(3, 1, 5),
(4, 2, 1),
(5, 2, 5),
(6, 2, 6),
(7, 3, 1),
(8, 4, 5),
(9, 4, 6);
あなたは何かを試してみましたまだですか? SOは無料のコード作成サービスではありません。 –
ええ、私は知っています。私は自分の投稿を編集しました。 –