当前位置: 首页 > 面试题库 >

如何在Redshift中创建日期表?

彭俊智
2023-03-14
问题内容

tl; dr:我想在Redshift中生成一个日期表,以使报表更易于生成。最好不需要在Redshift中已经有大表,而需要上传一个csv文件

长版:我正在处理一份报告,其中我必须平均一周中每天创建的新项目。日期范围可能跨越数月或更长时间,因此可能有5个星期一,但只有4个星期日,这可能会使数学有些棘手。另外,我不能保证每天都有一个实例,尤其是一旦用户开始切片数据时。其中,这是BI工具的绊脚石。

解决此问题的最佳方法很可能是日期表。但是,大多数有关日期表的教程都使用Redshift不可用或不完全支持的SQL命令(我在看着您,
generate_series )。

有没有一种简单的方法可以在Redshift中生成日期表?

我尝试使用的代码:(基于这个也不起作用的建议:http : //elliot.land/post/building-a-date-dimension-
table-in-redshift

CREATE TABLE facts.dates (
  "date_id"              INTEGER                     NOT NULL PRIMARY KEY,

  -- DATE
  "full_date"            DATE                        NOT NULL,

  -- YEAR
  "year_number"          SMALLINT                    NOT NULL,
  "year_week_number"     SMALLINT                    NOT NULL,
  "year_day_number"      SMALLINT                    NOT NULL,

  -- QUARTER
  "qtr_number"           SMALLINT                    NOT NULL,

  -- MONTH
  "month_number"         SMALLINT                    NOT NULL,
  "month_name"           CHAR(9)                     NOT NULL,
  "month_day_number"     SMALLINT                    NOT NULL,

  -- WEEK
  "week_day_number"      SMALLINT                    NOT NULL,

  -- DAY
  "day_name"             CHAR(9)                     NOT NULL,
  "day_is_weekday"       SMALLINT                    NOT NULL,
  "day_is_last_of_month" SMALLINT                    NOT NULL
) DISTSTYLE ALL SORTKEY (date_id)
;


INSERT INTO facts.dates
(
   "date_id"
  ,"full_date"
  ,"year_number"
  ,"year_week_number"
  ,"year_day_number"

  -- QUARTER
  ,"qtr_number"

  -- MONTH
  ,"month_number"
  ,"month_name"
  ,"month_day_number"

  -- WEEK
  ,"week_day_number"

  -- DAY
  ,"day_name"
  ,"day_is_weekday"
  ,"day_is_last_of_month"
)
  SELECT
    cast(seq + 1 AS INTEGER)                                      AS date_id,

    -- DATE
    datum                                                         AS full_date,

    -- YEAR
    cast(extract(YEAR FROM datum) AS SMALLINT)                    AS year_number,
    cast(extract(WEEK FROM datum) AS SMALLINT)                    AS year_week_number,
    cast(extract(DOY FROM datum) AS SMALLINT)                     AS year_day_number,

    -- QUARTER
    cast(to_char(datum, 'Q') AS SMALLINT)                         AS qtr_number,

    -- MONTH
    cast(extract(MONTH FROM datum) AS SMALLINT)                   AS month_number,
    to_char(datum, 'Month')                                       AS month_name,
    cast(extract(DAY FROM datum) AS SMALLINT)                     AS month_day_number,

    -- WEEK
    cast(to_char(datum, 'D') AS SMALLINT)                         AS week_day_number,

    -- DAY
    to_char(datum, 'Day')                                         AS day_name,
    CASE WHEN to_char(datum, 'D') IN ('1', '7')
      THEN 0
    ELSE 1 END                                                    AS day_is_weekday,
    CASE WHEN
      extract(DAY FROM (datum + (1 - extract(DAY FROM datum)) :: INTEGER +
                        INTERVAL '1' MONTH) :: DATE -
                       INTERVAL '1' DAY) = extract(DAY FROM datum)
      THEN 1
    ELSE 0 END                                                    AS day_is_last_of_month
  FROM
    -- Generate days for 81 years starting from 2000.
    (
      SELECT
        '2000-01-01' :: DATE + generate_series AS datum,
        generate_series                        AS seq
      FROM generate_series(0,81 * 365 + 20,1)
    ) DQ
  ORDER BY 1;

哪个抛出这个错误

[Amazon](500310) Invalid operation: Specified types or functions (one per INFO message) not supported on Redshift tables.;
1 statement failed.

…因为我假设在Redshift中同一命令中不允许INSERT和 generate_series


问题答案:

在问这个问题时,我知道了。哎呀。

我从“事实”模式开始。

CREATE SCHEMA facts;

运行以下命令以启动数字表:

create table facts.numbers
(
  number int PRIMARY KEY
)
;

使用它来生成您的号码列表。我用了一百万开始

SELECT ',(' || generate_series(0,1000000,1) || ')'
;

然后将您的结果中的数字复制粘贴到下面的查询中,位于VALUES之后:

INSERT INTO facts.numbers
VALUES
 (0)
,(1)
,(2)
,(3)
,(4)
,(5)
,(6)
,(7)
,(8)
,(9)
-- etc

^确保从复制粘贴的数字列表中删除前导逗号

一旦有了数字表,就可以生成一个日期表(同样,从elliot land http://elliot.land/post/building-a-date-
dimension-table-in-redshift
窃取代码):

CREATE TABLE facts.dates (
  "date_id"              INTEGER                     NOT NULL PRIMARY KEY,

  -- DATE
  "full_date"            DATE                        NOT NULL,

  -- YEAR
  "year_number"          SMALLINT                    NOT NULL,
  "year_week_number"     SMALLINT                    NOT NULL,
  "year_day_number"      SMALLINT                    NOT NULL,

  -- QUARTER
  "qtr_number"           SMALLINT                    NOT NULL,

  -- MONTH
  "month_number"         SMALLINT                    NOT NULL,
  "month_name"           CHAR(9)                     NOT NULL,
  "month_day_number"     SMALLINT                    NOT NULL,

  -- WEEK
  "week_day_number"      SMALLINT                    NOT NULL,

  -- DAY
  "day_name"             CHAR(9)                     NOT NULL,
  "day_is_weekday"       SMALLINT                    NOT NULL,
  "day_is_last_of_month" SMALLINT                    NOT NULL
) DISTSTYLE ALL SORTKEY (date_id)
;


INSERT INTO facts.dates
(
   "date_id"
  ,"full_date"
  ,"year_number"
  ,"year_week_number"
  ,"year_day_number"

  -- QUARTER
  ,"qtr_number"

  -- MONTH
  ,"month_number"
  ,"month_name"
  ,"month_day_number"

  -- WEEK
  ,"week_day_number"

  -- DAY
  ,"day_name"
  ,"day_is_weekday"
  ,"day_is_last_of_month"
)
  SELECT
    cast(seq + 1 AS INTEGER)                                      AS date_id,

    -- DATE
    datum                                                         AS full_date,

    -- YEAR
    cast(extract(YEAR FROM datum) AS SMALLINT)                    AS year_number,
    cast(extract(WEEK FROM datum) AS SMALLINT)                    AS year_week_number,
    cast(extract(DOY FROM datum) AS SMALLINT)                     AS year_day_number,

    -- QUARTER
    cast(to_char(datum, 'Q') AS SMALLINT)                         AS qtr_number,

    -- MONTH
    cast(extract(MONTH FROM datum) AS SMALLINT)                   AS month_number,
    to_char(datum, 'Month')                                       AS month_name,
    cast(extract(DAY FROM datum) AS SMALLINT)                     AS month_day_number,

    -- WEEK
    cast(to_char(datum, 'D') AS SMALLINT)                         AS week_day_number,

    -- DAY
    to_char(datum, 'Day')                                         AS day_name,
    CASE WHEN to_char(datum, 'D') IN ('1', '7')
      THEN 0
    ELSE 1 END                                                    AS day_is_weekday,
    CASE WHEN
      extract(DAY FROM (datum + (1 - extract(DAY FROM datum)) :: INTEGER +
                        INTERVAL '1' MONTH) :: DATE -
                       INTERVAL '1' DAY) = extract(DAY FROM datum)
      THEN 1
    ELSE 0 END                                                    AS day_is_last_of_month
  FROM
    -- Generate days for 81 years starting from 2000.
    (
      SELECT
        '2000-01-01' :: DATE + number AS datum,
        number                        AS seq
      FROM facts.numbers
      WHERE number between 0 and 81 * 365 + 20
    ) DQ
  ORDER BY 1;

^请务必在所需日期范围的末尾设置数字



 类似资料:
  • 问题内容: 我正在尝试在Amazon Redshift中创建索引,但收到错误 是一个整数字段。 问题答案: 如果尝试在Redshift表上创建索引(带有名称): 您会收到错误消息 执行SQL命令时发生错误:在“ SomeTable”(“ UserId”)上创建索引IX1错误:Redshift表不支持SQL命令“在” SomeTable“(” UserId“))上创建索引IX1。 这是因为,与其他数

  • 本文向大家介绍如何在MySQL中创建和更新表的日期?,包括了如何在MySQL中创建和更新表的日期?的使用技巧和注意事项,需要的朋友参考一下 使用MySQL中的create_time或update_time获取创建和更新表的确切日期。 首先,使用SHOW命令。语法如下 我们正在考虑我们的数据库“ test3”,该数据库已经有一些表 现在使用以下查询显示数据库test3中的所有表 以下是输出 查询如下

  • 本文向大家介绍如何从Swift Xcode中的日期创建日期对象?,包括了如何从Swift Xcode中的日期创建日期对象?的使用技巧和注意事项,需要的朋友参考一下 来自Objective C- Background,现在我们不需要使用NSDate,因为Swift已定义了自己的结构类型Date。日期桥接到NSDate类。您可以在与Objective-C API交互的代码中互换使用这些代码。 要了解有

  • 问题内容: 我正在处理一批文件,这些文件包含有关同一对象生命周期不同时间的信息,而订购它们的唯一方法是按创建日期排序。我正在使用这个: 但这似乎不起作用。我究竟做错了什么?在Linux下还有其他更可靠/简单的方法来获取文件创建日期吗? 问题答案: fstat适用于文件描述符,而不适用于FILE结构。最简单的版本: 您需要通过检查sys / stat.h或使用某种autoconf构造来确定系统的st

  • 我想在Amazon Redshift中生成一个日期和时间表。下面的查询可以在Postgresql 9.1及以上版本中运行,但不幸的是,我们仅限于Amazon Redshift,这导致了错误:“函数generate_series不存在。”您在8.02中生成时间序列(如结果表)时的帮助将非常感谢。 编辑:我能够用下面的代码生成我想要的时间序列,但无法将它们创建到Redshift表中。错误消息为: “红

  • 问题内容: 如何在SQL(T-SQL)中构造本机日期数据类型值? 我添加了一些示例,但请提供您自己的示例。我的示例假定月份和年份以整数值存储(或随时可用),但是 您的 示例可能假定日期和月份(或其他形式)以文本存储。我看不到未来。给我一个惊喜 问题答案: 为什么将输入数据作为字符串,最明显(因此不足为奇,对不起)的解决方案之一是: