【问题标题】:How to retrieve only the year from timestamp column?如何从时间戳列中仅检索年份?
【发布时间】:2015-11-27 10:14:21
【问题描述】:

我有以下在 Postgres 9.3 上正确运行的查询:

select distinct date_part('year', date_created) 
from "Topic";

目的是只返回列date_created 上的不同年份,它是这样创建的:

date_created  | timestamp with time zone | not null default now()

我需要将其转换为 SQLAlchemy 查询,但我写的内容是在 date_created 上选择 distinct,而不是在年份上,并返回整行,而不仅仅是不同的值:

topics = Topic.query.distinct(func.date_part('YEAR', Topic.date_created)).all()

我怎样才能从表格主题中只获得不同的年份?

【问题讨论】:

    标签: python postgresql sqlalchemy flask-sqlalchemy


    【解决方案1】:

    这里有两种变体:

    使用 ORM:

    from sqlalchemy import func, distinct
    
    result = session.query(distinct(func.date_part('YEAR', Topic.date_created)))
    for row in result:
        print(row[0])
    

    SQL 表达式:

    from sqlalchemy import func, select, distinct
    
    query = select([distinct(func.date_part('YEAR', Topic.date_created))])
    for row in session.execute(query):
            print(row[0])
    

    【讨论】:

      【解决方案2】:

      除了 SQL Alchemy 语法,您的查询中存在潜在问题

      您的数据类型是timestamptz (timestamp with time zone),这是一个不错的选择。 但是,您不能可靠地分辨年份单独形成timestamptz,您需要另外指定时区。如果您不这样做,会话的当前时区设置将被静默应用,这可能适合您,也可能不适合您。

      想想除夕夜:timestamptz '2016-01-01 04:00:00+00' - 这是哪一年?

      在欧洲是 2016 年,但在美国仍然是 2015 年。
      您应该使用 AT TIME ZONE 构造明确这一点,以避免偷偷摸摸的错误:

      SELECT extract(year FROM timestamptz '2016-01-01 04:00:00+00'
                               AT TIME ZONE 'America/New_York') AS year;
      

      详细解释:

      date_part() and extract() do the same in Postgres, extract() 是 SQL 标准,所以还是使用它吧。

      SQL Fiddle.

      顺便说一句,您也可以:

      SELECT extract(year FROM date_created) AS year
      FROM   "Topic"
      GROUP  BY 1;
      

      【讨论】:

      • 感谢您的提醒!我正在接受另一个答案,因为它更接近我的问题,但这很好。
      【解决方案3】:

      使用extract函数:

      session.query(func.extract(Topic.date_created, 'year'))
      

      这是一个概念代码,未经测试。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-31
      • 1970-01-01
      • 1970-01-01
      • 2012-05-07
      • 2013-03-16
      • 2020-07-09
      • 2022-11-20
      • 1970-01-01
      相关资源
      最近更新 更多