【问题标题】:What data type can I use for separate month (January, February, etc) and year (2012, 2020, etc) columns?我可以为单独的月份(1 月、2 月等)和年份(2012、2020 等)列使用什么数据类型?
【发布时间】:2021-11-01 23:20:46
【问题描述】:

我目前正在尝试将 csv 文件复制到 PostgreSQL 中创建的表中。该文件包含以下格式的月份和年份列 --> 月份:1 月、2 月、3 月、4 月等。年份:2001、2002、2003、2004 等。

请在创建的表中为这些列使用什么数据类型。我尝试使用 DATE,但它不起作用。这是我之前尝试过的;

CREATE TABLE IBREW (
sales_id int,
months date,
years date,
)

【问题讨论】:

  • 很期待将这对(2020 年 1 月)转换为 2020-01-01 日期

标签: sql postgresql sqldatatypes


【解决方案1】:

如果您只想存储一个月和一年,请使用两个整数(甚至smallint)。我不会存储月份names,因为处理数字会让你的生活更轻松——考虑排序或应用范围条件。当您在应用程序中显示数据时,您始终可以将数字转换为名称。

create table ibrew 
(
  sales_id int, 
  month int check (month between 1 and 12), 
  year int check (year > 0)
)

【讨论】:

    【解决方案2】:

    如果您无法转换月份数据,则需要使用 enumerablecharacter type 表示月份。年份将是一个整数。

    枚举:

    CREATE TYPE month AS ENUM ('January', 'February', 'March', ...);
    create table ibrew 
    (
      sales_id int, 
      month month, 
      year int
    )
    

    文本月份:

    create table ibrew 
    (
      sales_id int, 
      month text, 
      year int
    )
    

    如果这对您的应用程序有帮助,您还可以使用 varchar 或 at 约束来限制月份的大小。

    阅读更多关于postgres data types的信息。

    【讨论】:

      【解决方案3】:

      不要将其存储为月份名称和年份,将其存储为实际日期,您始终可以从日期中获取您想要的任何格式。如果你存储为单独的列,你最终会跳过各种圈子来简单地获得 DATE 类型给你的东西。那么问题就变成了:如何在给定月份名称和年份的情况下生成实际情况。 Postgres 提供了两个函数来救援MAKE_DATE 和一个数组函数ARRAY_POSITION
      第一步按日历顺序创建一个包含月份名称的数组,然后使用 array_position 转换为月份编号。第二步使用 make_date 过程中的结果来获取实际的 DATE。
      现在这可能会产生一个令人讨厌的查询,所以我会在 SQL 函数后面做整个事情。实际上没有必要,因为它包含在单个 SQL 语句中。

      create or replace 
      function make_real_date( month_name_in text   
                             , year_in       integer
                             ) 
         returns date 
        language sql 
      as $$
      with mlist (month_name) as 
           ( select array [ 'january'
                          , 'february'
                          , 'march'
                          , 'aprial'
                          , 'may'
                          , 'june'
                          , 'july'
                          , 'august'
                          , 'september'
                          , 'october'
                          , 'november' 
                          , 'december' 
                          ]
            ) --select * from mlist;  
      select make_date ( year  => year_in
                       , month => (select array_position(month_name, lower(month_name_in)) from mlist)  
                       , day   => 1
                       ) ;
      $$; 
      

      参见example here,注意:当月份名称无效时,函数返回null。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-09-26
        • 1970-01-01
        • 2021-01-15
        • 1970-01-01
        • 2020-11-11
        • 1970-01-01
        • 2016-08-30
        相关资源
        最近更新 更多