在Postgres 9.6中的函数/存储过程中,我希望使用一个CTE从两个不同的表中获取数据,如下所示:
WITH "CTE_from_table1" AS (SELECT column1, column2 FROM table1 WHERE id = $1),
"CTE_from_table2" AS (SELECT column1, column2 FROM table2 WHERE id = $2)
SELECT
COALESCE(
"CTE_from_table1".column1,
"CTE_from_table2".column1,
CASE WHEN "CTE_from_table1".column2 = 42 OR "CTE_from_table2".column2 = 42
THEN 'Something is 42' ELSE 'something else!' END
)
FROM "CTE_from_table1","CTE_from_table2";(重新定义了column1和column2的数据类型。两个表相同: column1是文本,column2是整数。)
只要定义了两个CTE,它就能工作。问题是:参数$1和/或$2可以是null,也可以包含根本不存在的is。在这种情况下,我期望得到结果something else!,因为前两个COALESCE参数计算为null,第三个参数是CASE WHEN,应该转到返回something else!的ELSE。
这是我的理论。但是,在实践中,只要其中一个CTE未定义/null,我就会得到null。我能做些什么?
发布于 2017-09-05 16:29:01
您的问题是FROM子句中可怕的逗号。简单的规则。。。不要在FROM子句中使用逗号。在这种情况下,您需要一个“外部交叉连接”。逗号执行“内部交叉连接”,因此如果CTE没有行,则不返回任何行。
不幸的是,OUTER CROSS JOIN不存在,所以您可以使用FULL OUTER JOIN
WITH "CTE_from_table1" AS (SELECT column1, column2 FROM table1 WHERE id = $1),
"CTE_from_table2" AS (SELECT column1, column2 FROM table2 WHERE id = $2)
SELECT COALESCE(ct1.column1, ct2.column1,
CASE WHEN 42 IN (ct1.column2, ct2.column2)
THEN 'Something is 42'
ELSE 'something else!'
END
)
FROM "CTE_from_table1" ct1 FULL OUTER JOIN
"CTE_from_table2" ct2
ON 1=1;我不太喜欢把CASE和COALESCE()混为一谈,所以我倾向于写:
SELECT (CASE WHEN ct1.column1 IS NOT NULL THEN ct1.column1
WHEN ct2.column1 IS NOT NULL THEN ct2.column1
WHEN 42 IN (ct1.column2, ct2.column2) THEN 'Something is 42'
ELSE 'something else!'
END)https://stackoverflow.com/questions/46059348
复制相似问题