具有默认属性值的SQL联接

具有默认属性值的SQL联接,sql,join,attributes,Sql,Join,Attributes,我有一个对象表、一个定义属性的表和一个包含对象属性值的表: OBJECTS: ID | ... ----+----- 1 | ... 2 | ... ATTRIBUTES: KEY | DEFAULT -----+--------- a1 | xyz a2 | abc a3 | 123 OBJECT_ATTRIBUTES: OBJECT_ID | KEY | VALUE -----------+------+------- 1 | a1 |

我有一个对象表、一个定义属性的表和一个包含对象属性值的表:

OBJECTS:
ID  | ...
----+-----
1   | ...
2   | ...

ATTRIBUTES:
KEY  | DEFAULT
-----+---------
a1   | xyz
a2   | abc
a3   | 123

OBJECT_ATTRIBUTES:
OBJECT_ID  | KEY  | VALUE 
-----------+------+-------
1          | a1   | abcd
1          | a2   | xyzw
2          | a3   | 12345
因此,每个对象都可以为其属性定义值,否则应使用该属性的默认值

现在我需要一个select,它将所有对象与所有属性连接起来,并在不存在OBJECT_attributes记录时替换默认值:

INTENDED QUERY RESULT:
OBJECT_ID  | ...  | KEY  | VALUE 
-----------+------+------+-------
1          | ...  | a1   | abcd
1          |      | a2   | xyzw
1          |      | a3   | 123 <- filled in default
2          |      | a1   | xyz <- filled in default
2          |      | a2   | abc <- filled in default
2          |      | a3   | 12345

但是我必须手动填充空格。

您需要获得表对象与属性的笛卡尔乘积,以便所有对象都包含所有属性

SELECT  a.*,
        b.key,
        COALESCE(c.value, b.default) Value
FROM    Objects a
        CROSS JOIN Attributes b
        LEFT JOIN Object_Attributes c
            ON  a.ID = c.object_id AND
                b.key = c.key
ORDER   BY a.ID, b.key

您需要获得具有属性的表对象的笛卡尔积,以便所有对象都包含所有属性

SELECT  a.*,
        b.key,
        COALESCE(c.value, b.default) Value
FROM    Objects a
        CROSS JOIN Attributes b
        LEFT JOIN Object_Attributes c
            ON  a.ID = c.object_id AND
                b.key = c.key
ORDER   BY a.ID, b.key

您可以从对象属性中获取所有现有条目,然后从对象和属性中添加所有缺少的组合:


您可以从对象属性中获取所有现有条目,然后从对象和属性中添加所有缺少的组合:


这适用于几乎所有的RDBMS。顺便问一下,你在用什么?博士后。不过,这只是一个最小的工作示例,我的情况要复杂得多:这几乎适用于所有RDBMS。顺便问一下,你在用什么?博士后。不过,这只是一个最小的工作示例,我的情况要复杂得多:
SELECT OBJECT_ID, KEY, VALUE
FROM OBJECT_ATTRIBUTES

UNION ALL

SELECT o.ID, a.KEY, a.DEFAULT
FROM OBJECTS AS o
CROSS JOIN ATTRIBUTES AS a
WHERE NOT EXISTS (
  SELECT *
  FROM OBJECT_ATTRIBUTES
  WHERE OBJECT_ID = o.ID AND KEY = a.KEY
);