PostgreSQL 中的条件 CTE
Conditional CTE in PostgreSQL
我正在尝试编写动态查询。我已尽力简化这一点。 @Condition
和 @Filter
是查询的动态输入。
有两种情况:
- 如果
@Condition
是 TRUE
,则不要在存在任何 metadata
时过滤 data
- 否则,找到
metadata
中与特定文件管理器匹配的行,并在这些行上过滤 data
。
伪代码有点像这样:
WITH selected_metadata AS (
IF (@Condition = TRUE) {
-- Do not filter on metadata
SELECT NULL;
}
ELSE {
-- Find the matching metadata rows
SELECT id FROM metadata WHERE field = @Filter
}
)
SELECT
*
FROM data
WHERE
(
-- Ignore the metadata filter
selected_metadata IS NULL
OR
-- Filter on metadata
data.metadataid IN (selected_metadata)
)
...more filters
我认为在没有 CTE 的情况下可能有更简单的方法来执行此操作,但由于查询在现实生活中的样子,我认为我需要将其拆分以尽量减少复杂性。
我认为您可以尝试在 where 而不是直接在 CTE 中设置这些条件。
SELECT
*
FROM data
WHERE
(
-- Ignore the metadata filter
@Condition = TRUE
OR
-- Filter on metadata
@Condition = FALSE AND data.metadataid IN (SELECT ID FROM selected_metadata AND field = @Filter)
)
...more filters
尝试这样的事情:
WITH selected_metadata AS (
-- Find the matching metadata rows
SELECT id FROM metadata WHERE field = @Filter OR @Condition <> TRUE
)
SELECT ...
我正在尝试编写动态查询。我已尽力简化这一点。 @Condition
和 @Filter
是查询的动态输入。
有两种情况:
- 如果
@Condition
是TRUE
,则不要在存在任何metadata
时过滤 - 否则,找到
metadata
中与特定文件管理器匹配的行,并在这些行上过滤data
。
data
伪代码有点像这样:
WITH selected_metadata AS (
IF (@Condition = TRUE) {
-- Do not filter on metadata
SELECT NULL;
}
ELSE {
-- Find the matching metadata rows
SELECT id FROM metadata WHERE field = @Filter
}
)
SELECT
*
FROM data
WHERE
(
-- Ignore the metadata filter
selected_metadata IS NULL
OR
-- Filter on metadata
data.metadataid IN (selected_metadata)
)
...more filters
我认为在没有 CTE 的情况下可能有更简单的方法来执行此操作,但由于查询在现实生活中的样子,我认为我需要将其拆分以尽量减少复杂性。
我认为您可以尝试在 where 而不是直接在 CTE 中设置这些条件。
SELECT
*
FROM data
WHERE
(
-- Ignore the metadata filter
@Condition = TRUE
OR
-- Filter on metadata
@Condition = FALSE AND data.metadataid IN (SELECT ID FROM selected_metadata AND field = @Filter)
)
...more filters
尝试这样的事情:
WITH selected_metadata AS (
-- Find the matching metadata rows
SELECT id FROM metadata WHERE field = @Filter OR @Condition <> TRUE
)
SELECT ...