Bigquery:将缩写的月份字符串转换为数字

时间:2016-09-08 22:05:26

标签: google-bigquery

在Bigquery中:

如何将缩写的月份转换为月份的数字?

输入可以是:01-feb-1980或1980年2月1日或01-FEB-1980 输出:02

3 个答案:

答案 0 :(得分:2)

以下是纯标准SQL解决方案,它不需要UDF,并且依赖PARSE_DATE函数,尤其是%b format specifier上的函数:

select extract(month from parse_date('%d-%b-%Y', d)) from
unnest(['01-FEB-1980', '01-feb-1980', '01-Feb-1980']) d

返回2, 2, 2

答案 1 :(得分:0)

有时日期集成在标准格式化时可能会很棘手。

这是其中一种情况,其中日期是1980年2月1日或01-FEB-1980或01-feb-1980

select 
month_str as month_abbriviation,
(case 
when upper(month_str) = 'JAN' then '01' 
when upper(month_str) = 'FEB' then '02' 
when upper(month_str) = 'MAR' then '03' 
when upper(month_str) = 'APR' then '04' 
when upper(month_str) = 'MAY' then '05' 
when upper(month_str) = 'JUN' then '06' 
when upper(month_str) = 'JUL' then '07' 
when upper(month_str) = 'AUG' then '08' 
when upper(month_str) = 'SEP' then '09' 
when upper(month_str) = 'OCT' then '10' 
when upper(month_str) = 'NOV' then '11' 
when upper(month_str) = 'DEC' then '12' 
end) as month_number
from (select regexp_extract('01-Feb-1980', r'..-(...)-....') as month_str);`

答案 2 :(得分:0)

标准SQL具有很好的功能,称为Scalar UDF
目前支持两种语言 - JavaScript UDFSQL UDF

下面的示例通过在主查询之外提取转换逻辑来帮助清理主代码,因此代码可以更好/更容易读取和维护(绝对是个人偏好

CREATE TEMPORARY FUNCTION MONTH_STRING(x STRING)
RETURNS STRING AS (LOWER(REGEXP_EXTRACT(x, r'-(...)-')));

CREATE TEMPORARY FUNCTION MONTH_TO_NUMBER(x STRING)
RETURNS STRING AS (CASE 
  WHEN x='jan' THEN '01' WHEN x='feb' THEN '02' WHEN x='mar' THEN '03' WHEN x='apr' THEN '04' 
  WHEN x='may' THEN '05' WHEN x='jun' THEN '06' WHEN x='jul' THEN '07' WHEN x='aug' THEN '08' 
  WHEN x='sep' THEN '09' WHEN x='oct' THEN '10' WHEN x='nov' THEN '11' WHEN x='dec' THEN '12' 
END );

WITH yourTable AS (
  SELECT '1-feb-1980'AS dt UNION ALL
  SELECT '01-Mar-1980' AS dt UNION ALL
  SELECT '01-SEP-1980' AS dt
)
SELECT 
  dt, 
  MONTH_TO_NUMBER(MONTH_STRING(dt)) AS month_number
FROM yourTable
  

选项2

不知怎的,我不喜欢MONTH_TO_NUMBER()函数,因为它对WHEN THEN事物的沉重感

这个功能的版本对我来说看起来更优雅(不是很老实 - 但看起来仍然很重 - 但我喜欢尝试

CREATE TEMPORARY FUNCTION MONTH_TO_NUMBER(x STRING)
RETURNS STRING AS ((
  SELECT SUBSTR(CAST(101 + num AS STRING), 2) FROM  
  UNNEST(['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec']) AS list 
  WITH OFFSET AS num WHERE list = x));
  

选项3

返回所有没有UDF的内联

WITH yourTable AS (
  SELECT '1-feb-1980'AS dt UNION ALL
  SELECT '01-Mar-1980' AS dt UNION ALL
  SELECT '01-SEP-1980' AS dt
)
SELECT 
  dt,
  (SELECT SUBSTR(CAST(101 + num AS STRING), 2) 
   FROM UNNEST(['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec']) AS list 
   WITH OFFSET AS num 
   WHERE list = LOWER(REGEXP_EXTRACT(dt, r'-(...)-'))) AS month_number
FROM yourTable