Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 为多个表构建复杂查询_Sql_Postgresql - Fatal编程技术网

Sql 为多个表构建复杂查询

Sql 为多个表构建复杂查询,sql,postgresql,Sql,Postgresql,我有六张桌子: Keys( id, name ) Values( id, name ) PropertyRoles( id, name ) Properties( id, name, key_id, value_id, role_id ) Components( id, name, type ) ComponentProperties( id, component_id, property_id, proprole_id ) 作为输入,我有一个键值对列表。我想从角色名为X的输入列表中找到至少有

我有六张桌子:

Keys( id, name )
Values( id, name )
PropertyRoles( id, name )
Properties( id, name, key_id, value_id, role_id )
Components( id, name, type )
ComponentProperties( id, component_id, property_id, proprole_id )
作为输入,我有一个键值对列表。我想从角色名为X的输入列表中找到至少有一个与键值对相关属性的所有组件。最后,我想收集有关已创建组件的所有数据(
id、name、properties
)。

有人能帮我建立相应的查询吗?
编辑:我完全不知道从哪里开始

SELECT c.id, c.name, p.name FROM components c 
INNER JOIN componentproperties cp ON cp.role = ( SELECT id FROM propertyroles WHERE name = 'primary' ) AND cp.component_id = c.id
INNER JOIN properties p ON p.key_id = ( SELECT id FROM keys WHERE name IN ( %1 ) ) AND  p.value_id = ( SELECT id FROM values WHERE name IN ( %2 ) )
UNION ALL
SELECT cp2.name FROM componentproperties cp2 WHERE cp2.id IN cp.id
UNION ALL
SELECT keys.name FROM keys WHERE keys.id IN %1
UNION ALL
SELECT values.name FROM values WHERE values.id IN %2
ORDER BY c.name;

对不起我的英语

有几种方法可以做到这一点,具体取决于您使用的Postgresql版本。我在这里通过多个子查询来解决它

注意:在
属性
表中指定属性的角色,但在
组件属性
中也有该角色。我假设您不希望在多个位置拥有相同的数据,因此在这里的解决方案中,我假设
ComponentProperties
的角色id不存在

要解决的第一个问题是如何将键:值对列表放入查询中,以便可以搜索它们

一种方法是创建(临时)表:

然后插入该表中的所有值

INSERT INTO key_value_role VALUES
('Key 1', 'Value 1', 'Role 1'),
('Key 2', 'Value 2', 'Role 1'),
('Key 2', 'Value 3', 'Role 1');
即使有一张临时桌子,也会很快变得一团糟。幸运的是,
可以单独使用:

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
如果您使用的是Postgresql>=9.3,则可以将数据作为序列化JSON字符串发送,并使用以下命令对键进行迭代:

在上面的示例中,我使用一个文本字符串,但我假设您将使用一个参数化查询并在程序中组合JSON序列化字符串

上述方法的限制是指定的键只能有一个值。也许这就足够了,但我想要一个灵活的解决方案,能够搜索每个键的多个值

Postgresql>=9.3中还有一个函数可以使用,但它需要一个基类型。基本类型可以是现有表,但也可以创建要使用的类型:

CREATE TYPE key_value_role as(
  key text,
  value text,
  role text
);
指定类型时,可以使用json\u populate\u记录集:

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"
 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"
 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_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"
 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"
现在,您可以为每个键填充多个值,还可以在同一查询中搜索不同的角色

下一个问题是将名称转换为ID。您没有指定ID的类型。我假设是整数

假设使用上述方法创建的列表被称为
list
,那么从名称到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   |   value   |  role
--------+------------+----------
 "Key 1" | "Value 1" | "Role 1"
 "Key 2" | "Value 2" | "Role 1"
 "Key 2" | "Value 3" | "Role 1"
 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"
 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_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"
 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"
通过上表,我们现在可以使用属性将其连接起来:

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 )
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 )
示例输出:

   key   |   value   |  role
--------+------------+----------
 "Key 1" | "Value 1" | "Role 1"
 "Key 2" | "Value 2" | "Role 1"
 "Key 2" | "Value 3" | "Role 1"
 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"
 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_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"
 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"
上表现在可以与ComponentProperties连接:

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 )
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 )
示例输出:

   key   |   value   |  role
--------+------------+----------
 "Key 1" | "Value 1" | "Role 1"
 "Key 2" | "Value 2" | "Role 1"
 "Key 2" | "Value 3" | "Role 1"
 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"
 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_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"
 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"
最后,将其与组件连接:

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 )
示例输出:

   key   |   value   |  role
--------+------------+----------
 "Key 1" | "Value 1" | "Role 1"
 "Key 2" | "Value 2" | "Role 1"
 "Key 2" | "Value 3" | "Role 1"
 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"
 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_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"
 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\u populate\u记录集:

-- 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);

你试过什么了吗?这不是免费的代码编写服务。是的,我知道。我已经编辑了我的帖子。嗯,这是一件大事!非常感谢您的详细解释。对于我来说,要完全理解这一点还有很长的路要走:)这不是一个初学者级别的查询,但是当它被分解成更小的部分时,应该不会太难理解。你会学到的。:)将数据格式化为JSON有一些“魔力”,您可能以前从未见过这种魔力。如果您对查询有什么不理解的地方,请告诉我,我会尽力解释。顺便说一句,当您提出这样的问题时,如果您提供创建表和插入一些测试数据的命令,就像我在回答的最后一部分中所做的那样,那就太好了。如果您决定更新您的问题,请随意复制我对您问题的回答中的相关部分。