编写 SQL 条件 [已编辑 - 需要精选] 的更好方法
Better way to write a SQL conditional [EDITED - Featured Needed]
我的 query
中有以下代码,但我不喜欢它。
(
(year + 1) = date_part('YEAR', CURRENT_DATE) OR
year = date_part('YEAR', CURRENT_DATE) OR
(year - 1) = date_part('YEAR', CURRENT_DATE)
)
有更好的形式来写这个条件吗?此条件的 objective 是 returns post 年和今天前一年之间的值。
编辑
我想要一个新功能:
SELECT DISTINCT ON (alias.year) alias.year, alias.another_column
FROM scheme.table AS alias
WHERE alias.active IS TRUE AND ABS(alias.year- date_part('YEAR', CURRENT_DATE)) IN (0,1)
ORDER BY alias.year, alias.another_column DESC;
上面的代码returns:
我要:
2017 - 8
2018 - 1
2019 - 1
发生这种情况是因为不存在 2019 年的任何记录,但是当某年不存在时,我需要 return 他在另一列中的值为 1。
ABS(年 - date_part('YEAR', CURRENT_DATE)) 在 (0,1)
不熟悉此 DBMS 的细节,但应该可以:
year BETWEEN (date_part('YEAR', CURRENT_DATE)-1) AND (date_part('YEAR', CURRENT_DATE)+1)
读起来也很像你的要求,这对以后维护你代码的人来说通常是件好事。
试试这个,between 将匹配介于低值和高值之间的值。
(date_part('YEAR', CURRENT_DATE) BETWEEN (year - 1) AND (year + 1))
编辑:
要完成您所说的,使用 common table expression and a RIGHT OUTER JOIN 可能更容易,常见的 table 表达式将填充范围内的年份(去年、今年、明年)
并将记录限制为 cte 中的记录,即使该年的 table 中不存在记录。
WITH RECURSIVE cte(year) AS(
VALUES (date_part('YEAR', CURRENT_DATE)-1)
UNION ALL
SELECT year+1 FROM cte WHERE year<date_part('YEAR', CURRENT_DATE)+1
)
SELECT DISTINCT ON (cte.year) alias.year, COALESCE(alias.another_column, 'value when blank') another_column
FROM scheme.table AS alias
RIGHT OUTER JOIN cte
ON alias.year = cte.year
WHERE alias.active IS TRUE
ORDER BY cte.year, alias.another_column DESC;
所以记录会这样显示
2017 - 8
2018 - 1
2019 - value when blank
如果删除 COALESCE 函数,它看起来像这样
2017 - 8
2018 - 1
2019 - NULL
编辑:
正如评论中所建议的,您也可以将 generate_series() to create the common table expression
. since date_part
returns a double precision
so you will have to CAST 用于 integer
我使用了两种方法,因此您有更多选择
WITH cte AS (
SELECT
generate_series(
date_part('YEAR', CURRENT_DATE)::integer-1
,CAST(date_part('YEAR', CURRENT_DATE) AS INTEGER)+1
) AS year
)
我的 query
中有以下代码,但我不喜欢它。
(
(year + 1) = date_part('YEAR', CURRENT_DATE) OR
year = date_part('YEAR', CURRENT_DATE) OR
(year - 1) = date_part('YEAR', CURRENT_DATE)
)
有更好的形式来写这个条件吗?此条件的 objective 是 returns post 年和今天前一年之间的值。
编辑
我想要一个新功能:
SELECT DISTINCT ON (alias.year) alias.year, alias.another_column
FROM scheme.table AS alias
WHERE alias.active IS TRUE AND ABS(alias.year- date_part('YEAR', CURRENT_DATE)) IN (0,1)
ORDER BY alias.year, alias.another_column DESC;
上面的代码returns:
我要:
2017 - 8
2018 - 1
2019 - 1
发生这种情况是因为不存在 2019 年的任何记录,但是当某年不存在时,我需要 return 他在另一列中的值为 1。
ABS(年 - date_part('YEAR', CURRENT_DATE)) 在 (0,1)
不熟悉此 DBMS 的细节,但应该可以:
year BETWEEN (date_part('YEAR', CURRENT_DATE)-1) AND (date_part('YEAR', CURRENT_DATE)+1)
读起来也很像你的要求,这对以后维护你代码的人来说通常是件好事。
试试这个,between 将匹配介于低值和高值之间的值。
(date_part('YEAR', CURRENT_DATE) BETWEEN (year - 1) AND (year + 1))
编辑:
要完成您所说的,使用 common table expression and a RIGHT OUTER JOIN 可能更容易,常见的 table 表达式将填充范围内的年份(去年、今年、明年) 并将记录限制为 cte 中的记录,即使该年的 table 中不存在记录。
WITH RECURSIVE cte(year) AS(
VALUES (date_part('YEAR', CURRENT_DATE)-1)
UNION ALL
SELECT year+1 FROM cte WHERE year<date_part('YEAR', CURRENT_DATE)+1
)
SELECT DISTINCT ON (cte.year) alias.year, COALESCE(alias.another_column, 'value when blank') another_column
FROM scheme.table AS alias
RIGHT OUTER JOIN cte
ON alias.year = cte.year
WHERE alias.active IS TRUE
ORDER BY cte.year, alias.another_column DESC;
所以记录会这样显示
2017 - 8
2018 - 1
2019 - value when blank
如果删除 COALESCE 函数,它看起来像这样
2017 - 8
2018 - 1
2019 - NULL
编辑:
正如评论中所建议的,您也可以将 generate_series() to create the common table expression
. since date_part
returns a double precision
so you will have to CAST 用于 integer
我使用了两种方法,因此您有更多选择
WITH cte AS (
SELECT
generate_series(
date_part('YEAR', CURRENT_DATE)::integer-1
,CAST(date_part('YEAR', CURRENT_DATE) AS INTEGER)+1
) AS year
)