这是一个最小化设置,包含2个表$('#myModal .modal-body').html($("[data-attr=1] > p").text());
和a
,每个表有3行:
b
这是一个LEFT JOIN,可以正常工作:
CREATE TABLE a (
id SERIAL PRIMARY KEY,
value TEXT
);
CREATE INDEX ON a (value);
CREATE TABLE b (
id SERIAL PRIMARY KEY,
value TEXT
);
CREATE INDEX ON b (value);
INSERT INTO a (value) VALUES ('x'), ('y'), (NULL);
INSERT INTO b (value) VALUES ('y'), ('z'), (NULL);
带输出:
SELECT * FROM a
LEFT JOIN b ON a.value IS NOT DISTINCT FROM b.value;
将“LEFT JOIN”更改为“FULL JOIN”会出错:
id | value | id | value
----+-------+----+-------
1 | x | |
2 | y | 1 | y
3 | | 3 |
(3 rows)
错误:只有merge-joinable或hash-joinable join条件支持FULL JOIN
有人可以回答:
什么是“合并可加入或可加入哈希的连接条件”以及为什么加入SELECT * FROM a
FULL JOIN b ON a.value IS NOT DISTINCT FROM b.value;
不符合此条件,但a.value IS NOT DISTINCT FROM b.value
完全正常?
似乎唯一的区别是如何处理NULL值。由于a.value = b.value
列已在两个表中编入索引,因此在value
查找上运行EXPLAIN
与查找非NULL
的值一样有效:
NULL
已经使用PostgreSQL 9.6.3和10beta1进行了测试。
已经有discussion about this issue,但它没有直接回答上述问题。
答案 0 :(得分:2)
PostgreSQL使用散列或合并连接实现FULL OUTER JOIN
。
要获得此类加入的资格,加入条件必须为
格式<expression using only left table> <operator> <expression using only right table>
现在您的连接条件 看起来像这样,但PostgreSQL没有特殊的IS NOT DISTINCT FROM
运算符,因此它会将您的条件解析为:
(NOT ($1 IS DISTINCT FROM $2))
这样的表达式不能用于散列或合并连接,因此错误消息。
我可以想办法解决这个问题:
SELECT a_id, NULLIF(a_value, '<null>'),
b_id, NULLIF(b_value, '<null>')
FROM (SELECT id AS a_id,
COALESCE(value, '<null>') AS a_value
FROM a
) x
FULL JOIN
(SELECT id AS b_id,
COALESCE(value, '<null>') AS b_value
FROM b
) y
ON x.a_value = y.b_value;
如果<null>
列中没有出现value
,则该方法有效。
答案 1 :(得分:0)
我刚刚解决了这种情况,用&#34; TRUE&#34;替换ON条件,并移动原始&#34; ON&#34;将条件转换为WHERE子句。但是,我不知道这对性能的影响。