【问题标题】:Better way to write a SQL conditional [EDITED - Featured Needed]编写 SQL 条件的更好方法 [已编辑 - 需要精选]
【发布时间】:2018-04-23 17:23:51
【问题描述】:

我的query 中有下面的代码,但我不喜欢它。

     (
       (year + 1) = date_part('YEAR', CURRENT_DATE) OR
       year = date_part('YEAR', CURRENT_DATE) OR
       (year - 1) = date_part('YEAR', CURRENT_DATE)
     )

有更好的形式来写这个条件吗?此条件的目标是返回今天的后一年和前一年之间的值。

编辑

我想要一个新功能:

  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;

上面的代码返回:

我想要:

2017 - 8
2018 - 1
2019 - 1

发生这种情况是因为 2019 年不存在任何记录,但当某年不存在时,我需要在另一列中返回值 1。

【问题讨论】:

  • 我去试试更新问题@Morpheus
  • 为什么 2019 年要使用 1 而不是 0

标签: sql postgresql ansi-sql


【解决方案1】:

试试这个,中间值将匹配低值和高值之间的值。

(date_part('YEAR', CURRENT_DATE) BETWEEN (year - 1) AND (year + 1))

编辑:

要完成您所说的,使用common table expressionRIGHT OUTER JOIN 可能更容易,公用表表达式将填充范围内的年份(去年、今年、明年) 并将记录限制为 cte 中的内容,即使该年份的表中不存在记录。

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

编辑:

根据 cmets 的建议,您也可以使用 generate_series() 创建 common table expression。因为date_part 返回一个double precision,所以你必须将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
)

【讨论】:

  • CTE 可以简化为对generate_series()的一次调用
【解决方案2】:

ABS(year - date_part('YEAR', CURRENT_DATE)) IN (0,1)

【讨论】:

  • 谢谢!!!您可以使用功能更新您的答案吗?如果不存在 2019 年记录,我可能会看到 2019 年
【解决方案3】:

不熟悉此 DBMS 的细节,但应该可以:

year BETWEEN (date_part('YEAR', CURRENT_DATE)-1) AND (date_part('YEAR', CURRENT_DATE)+1)

它也像您的要求一样,这对于将来维护您的代码的人来说通常是一件好事。

【讨论】:

    猜你喜欢
    • 2020-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 2020-09-06
    • 2011-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多