【问题标题】:SQL Split MM and YY and Concat with StringSQL 拆分 MM 和 YY 以及 Concat 与字符串
【发布时间】:2020-12-30 21:30:00
【问题描述】:

提前感谢您的帮助!

我有一个日期字段 (A.event_dt),我用它来创建新列,如下所示(一直到 12 月)。

to_char(A.event_dt, 'YYYYMM') as Event_Month,

case when ROW_NUMBER() OVER (PARTITION BY B.emp_nbr, E.cntry_enti_nbr, Event_Month order by A.event_dt asc) = 1  then 1 else 0 end as Unique_Event,


count(distinct concat(B.emp_nbr, E.cntry_enti_nbr, A.event_dt)),

case when CAST(A.event_dt as DATE FORMAT 'MM')(char(2)) = '06' then 1 else '' end as Jun,
case when CAST(A.event_dt as DATE FORMAT 'MM')(char(2)) = '07' then 1 else '' end as Jul,
case when CAST(A.event_dt as DATE FORMAT 'MM')(char(2)) = '08' then 1 else '' end as Aug,
case when CAST(A.event_dt as DATE FORMAT 'MM')(char(2)) = '09' then 1 else '' end as Sep,
case when CAST(A.event_dt as DATE FORMAT 'MM')(char(2)) = '10' then 1 else '' end as Oct,

我也想加上YY。

样本数据、当前输出和所需数据输出:

....EVENT_DT.....CURRENT OUTPUT......DESIRED DATA OUTPUT
....1/31/2020..........Jan................Jan20
....2/35/2019..........Feb................Feb19
....3/15/2020..........Mar................Mar20

所需的输出格式:

....EVENT_DT.....Feb19......Jan20..........Mar20
....2/25/2019........1..........................
....1/31/2020..................1................
....3/15/2020..............................1

编辑: 我尝试了下面的代码,但是出现错误: (预计在 'concat' 关键字和 '('.) 之间会出现类似 ',' 的内容:

case when CAST(A.event_dt as DATE FORMAT 'MM')(char(2)) = '06' then 1 else '' end as concat('Jun',CAST(A.event_dt as DATE FORMAT 'YY')(char(2)))

编辑: 我也尝试过这段代码,但是出现错误: "'AS' 关键字和 '(' 之间的名称或 unicode 分隔标识符之类的东西。

case when extract(month from A.ramp_dt) = '12' then 1 else '' end as (to_char(A.ramp_dt, 'MonYYYY')),
case when extract(month from  A.ramp_dt) = '01' then 1 else '' end as (to_char(A.ramp_dt, 'MonYYYY')),
case when extract(month from  A.ramp_dt) = '02' then 1 else '' end as (to_char(A.ramp_dt, 'MonYYYY'))

【问题讨论】:

  • 请提供样本数据和期望的结果。
  • @Gordon Linoff - 你好……我已经根据要求的信息修改了我的原始帖子。
  • extract(month from event_dt) 返回一个数字月份。您不能动态创建列别名。
  • @dnoeth .... 您好 - 我修改了查询以使用“提取”方法。我仍在尝试创建列别名。最新尝试指示错误:extract(month from A.ramp_dt) = '12' then 1 else '' end as (to_char(A.ramp_dt, 'MonYYYY')) 的情况,extract(month from A.ramp_dt) = '01' then 1 else '' end as (to_char(A.ramp_dt, 'MonYYYY')), case when extract(month from A.ramp_dt) = '02' then 1 else '' end as (to_char(A.ramp_dt , 'MonYYYY'))
  • 同样,您不能动态创建列别名。你为什么要它?您已经知道该列中需要哪个月份,如果 2019 年 2 月和 2020 年 2 月有两行怎么办?

标签: sql date teradata concat


【解决方案1】:

也许你应该只使用to_char()?

to_char(a.event_dt, 'MMMMYY')

【讨论】:

  • 你好。我希望看到列中表示的数据,因为我也在计算唯一实例。我如何将其纳入案例陈述中?
【解决方案2】:

对于此类工作,我总是使用 ISO 日期。 并且 2 月 35 日不是有效日期,所以我将其设为 2 月 25 日。

有了它,您可以使用 DATE 类型上的 TO_CHAR() 函数完成所有操作。

喜欢这里:

-- this is test input, don't use in your query
WITH
dt(dt) AS (
          SELECT DATE '2020-01-31'
UNION ALL SELECT DATE '2019-02-25'
UNION ALL SELECT DATE '2020-03-15'
)
-- end of test input; real query starts here
SELECT
  dt AS event_dt
, TO_CHAR(dt,'Mon') AS current_output
, TO_CHAR(dt,'MonYY') AS desired_output
FROM dt;
-- out   event_dt  | current_output | desired_output 
-- out ------------+----------------+----------------
-- out  2020-01-31 | Jan            | Jan20
-- out  2019-02-25 | Feb            | Feb19
-- out  2020-03-15 | Mar            | Mar20

【讨论】:

  • 您好 - 感谢您的回复!所以我有更多的 event_dt 然后显示......我有大约。我的数据集中有 3K 行。我将如何修改此语句以使其更具活力? WITH dt(dt) AS (SELECT DATE '2020-01-31' UNION ALL SELECT DATE '2019-02-25' UNION ALL SELECT DATE '2020-03-15')
  • 只是不要使用 CTE。从您的实际表中选择。
  • @Andrew ...您好-问题是我也在尝试创建列别名。使用 MonYY。我最近的“尝试”表示一个错误:“在 'AS' 关键字和 '(' 之间存在类似名称或 unicode 分隔标识符的东西。extract(month from A.ramp_dt) = '12' then 1 else ''结束为 (to_char(A.ramp_dt, 'MonYYYY')), case when extract(month from A.ramp_dt) = '01' then 1 else '' end as (to_char(A.ramp_dt, 'MonYYYY')), case当 extract(month from A.ramp_dt) = '02' then 1 else '' end as (to_char(A.ramp_dt, 'MonYYYY'))
  • AS 关键字后面的任何内容都应该是列名,而不是表达式。如果它不符合数据库中对象名称的标准,则必须将其括在双引号中,因此 case when extract(month from A.ramp_dt) = '01' then 1 else '' end as "(to_char(A.ramp_dt, 'MonYYYY'))" 其中 1 或 0 的结果将在名为 (to_char(A.ramp_dt, 'MonYYYY')) 的列中。我敢打赌,这不是你所期望的。您能否将一个小的预期结果集粘贴到您的问题中,格式如我在回复中显示的那样,以-- out 开头的行?
  • @marcothesane ...您好!所以,我更改了添加双引号的代码: case when extract(month from A.ramp_dt) = '12' then 1 else '' end as "(to_char(A.ramp_dt, 'MonYYYY'))", case when extract(month from A.ramp_dt) = '01' then 1 else '' end as "(to_char(A.ramp_dt, 'MonYYYY'))", 当 extract(month from A.ramp_dt) = '02' then 1 else '' end as "(to_char(A.ramp_dt, 'MonYYYY'))" 但是,这些是我收到的列标题: (to_char(A.ramp_dt, 'MonYYYY')) (to_char(A.ramp_dt, ' MonYYYY')) (to_char(A.ramp_dt, 'MonYYYY')) 1 我的帖子包含所需输出的样本
【解决方案3】:

现在需要一个全新的答案,而且比您想象的要复杂。 我使用 Teradata 易失性表。一个用于您(或我的……)的示范性输入,一个用于垂直输出。

我使用垂直易失性表: a) 作为生成旋转查询脚本的输入 b) 作为我生成的脚本的输入

这意味着您需要在启动的同一会话中运行您生成的脚本,否则您的 volatile 表会同时消失。

CREATE VOLATILE TABLE dt(event_dt) 
-- your input
AS (
          SELECT DATE '2019-01-31'
UNION ALL SELECT DATE '2019-04-25'
UNION ALL SELECT DATE '2019-07-15'
UNION ALL SELECT DATE '2019-10-15'
UNION ALL SELECT DATE '2020-01-31'
UNION ALL SELECT DATE '2020-04-25'
UNION ALL SELECT DATE '2020-07-15'
UNION ALL SELECT DATE '2020-10-15'
)
ON COMMIT PRESERVE ROWS 
;

-- create a vertical table
-- count, for safety, if you have several events
-- per day.
CREATE VOLATILE TABLE vertical_per_month 
ON COMMIT PRESERVE ROWS 
AS (
  SELECT
     event_dt
  ,  YEAR(event_dt)*100+MONTH(event_dt) AS yearmonth
  , TO_CHAR(event_dt,'MonYY')          AS desired_output
  , COUNT(*) AS occ_count
  FROM dt
  GROUP BY 1,2,3
)
ON COMMIT PRESERVE ROWS 
;

-- test query ....
-- SELECT * FROM vertical_per_month;
-- out   event_dt  | yearmonth | desired_output | occ_count 
-- out ------------+-----------+----------------+-----------
-- out  2019-01-31 |    201901 | Jan19          |         1
-- out  2019-04-25 |    201904 | Apr19          |         1
-- out  2019-07-15 |    201907 | Jul19          |         1
-- out  2019-10-15 |    201910 | Oct19          |         1
-- out  2020-01-31 |    202001 | Jan20          |         1
-- out  2020-04-25 |    202004 | Apr20          |         1
-- out  2020-07-15 |    202007 | Jul20          |         1
-- out  2020-10-15 |    202010 | Oct20          |         1

-- write the output of the query below to a file,
-- and execute that file. This is how you do that in 
-- the psql front end batch processor of PostreSQL
-- check the syntax of BTEQ yourself ...
-- do not align output
\a
-- tuples only, no column names, no row count
\t
-- redirect output to "tmp.sql"
\o tmp.sql
SELECT 
  CASE ROW_NUMBER() OVER(ORDER BY yearmonth)
    WHEN 1 THEN 'SELECT'||CHR(10)||'  event_dt'||CHR(10)||', '
    ELSE ', '
  END
||'MAX('
  ||'CASE desired_output WHEN '''||desired_output||''''
  ||' THEN '||occ_count::VARCHAR(5)
  ||' END'
||') AS "'||desired_output||'"'
|| CASE ROW_NUMBER() OVER(ORDER BY yearmonth DESC)
    WHEN 1 THEN CHR(10)||'FROM vertical_per_month'
              ||CHR(10)||'GROUP BY 1;'
    ELSE ''
  END AS "-- pivot query"
FROM vertical_per_month
ORDER BY yearmonth;
-- this output below; to file, and then execute ...
-- out SELECT
-- out   event_dt
-- out , MAX(CASE desired_output WHEN 'Jan19' THEN 1 END) AS "Jan19"
-- out , MAX(CASE desired_output WHEN 'Apr19' THEN 1 END) AS "Apr19"
-- out , MAX(CASE desired_output WHEN 'Jul19' THEN 1 END) AS "Jul19"
-- out , MAX(CASE desired_output WHEN 'Oct19' THEN 1 END) AS "Oct19"
-- out , MAX(CASE desired_output WHEN 'Jan20' THEN 1 END) AS "Jan20"
-- out , MAX(CASE desired_output WHEN 'Apr20' THEN 1 END) AS "Apr20"
-- out , MAX(CASE desired_output WHEN 'Jul20' THEN 1 END) AS "Jul20"
-- out , MAX(CASE desired_output WHEN 'Oct20' THEN 1 END) AS "Oct20"
-- out FROM vertical_per_month
-- out GROUP BY 1;

-- show the "(NULL)" literal in case of NULL values
\pset null (NULL)
-- stop outputting to "tmp.sql" and flush the file to disk.
\o
-- align again ( "\a" is a toggle)
\a
-- show more than just tuples again ("\t" is a toggle, too)
\t
-- run the freshly created "tmp.sql" on the still existing
-- volatile table
\i tmp.sql
-- out   event_dt  | Jan19  | Apr19  | Jul19  | Oct19  | Jan20  | Apr20  | Jul20  | Oct20  
-- out ------------+--------+--------+--------+--------+--------+--------+--------+--------
-- out  2019-01-31 |      1 | (NULL) | (NULL) | (NULL) | (NULL) | (NULL) | (NULL) | (NULL)
-- out  2019-04-25 | (NULL) |      1 | (NULL) | (NULL) | (NULL) | (NULL) | (NULL) | (NULL)
-- out  2019-07-15 | (NULL) | (NULL) |      1 | (NULL) | (NULL) | (NULL) | (NULL) | (NULL)
-- out  2019-10-15 | (NULL) | (NULL) | (NULL) |      1 | (NULL) | (NULL) | (NULL) | (NULL)
-- out  2020-01-31 | (NULL) | (NULL) | (NULL) | (NULL) |      1 | (NULL) | (NULL) | (NULL)
-- out  2020-04-25 | (NULL) | (NULL) | (NULL) | (NULL) | (NULL) |      1 | (NULL) | (NULL)
-- out  2020-07-15 | (NULL) | (NULL) | (NULL) | (NULL) | (NULL) | (NULL) |      1 | (NULL)
-- out  2020-10-15 | (NULL) | (NULL) | (NULL) | (NULL) | (NULL) | (NULL) | (NULL) |      1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-06
    • 2019-01-26
    • 1970-01-01
    • 1970-01-01
    • 2016-11-24
    • 2015-03-11
    • 1970-01-01
    • 2014-07-01
    相关资源
    最近更新 更多