我有一个对象表,一个定义属性的表,以及一个包含对象属性值的表:
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
因此每个对象都可以为其属性定义值,否则应该使用该属性的default
。
现在我需要一个选择,它将连接所有具有所有属性的对象,并在default
记录不存在时替换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
如何在SQL中执行此操作?
在折叠之下:现在我只选择
SELECT * FROM OBJECT LEFT JOIN OBJECTS_ATTRIBUTES ON ID = OBJECT_ID
但是我必须手动填写空白。
答案 0 :(得分:3)
您需要使用Objects
获取表Attributes
的笛卡尔积,以便所有对象都包含所有属性。
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
答案 1 :(得分:1)
您可以从OBJECT_ATTRIBUTES
获取所有现有条目,然后从OBJECTS
和ATTRIBUTES
添加(UNION ALL)缺少的组合:
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
);