SnowSQL 到 Select 日期和时间分开

SnowSQL to Select Day & Time Separately

来源是三列,其中第三列 (HOURS) 是 VARCHAR 类型并且它具有 CSV 值:

Monday, 10:30AM–12AM, Tuesday, 10:30AM–12AM, Wednesday, 10:30AM–12AM, Thursday, 10:30AM–12AM, Friday, 10:30AM–12AM, Saturday, 10:30AM–12AM, Sunday, 10:30AM–12AM

4 列中的所需输出,其中 HOURS 将转换为 DAY 和 SCHEDULE 列。

ID VENDOR DAY SCHEDULE
1001 ABC Monday 10:30AM–12AM
1001 ABC Tuesday 10:30AM–12AM
1001 ABC Wednesday 10:30AM–12AM
1001 ABC Thursday 10:30AM–12AM
1001 ABC Friday 10:30AM–12AM
1001 ABC Saturday 10:30AM–12AM
1001 ABC Sunday 10:30AM–12AM

所以 1 个 ID,具有 1 HOUR 的 VENDOR 需要转换为 7 行

这里是样本 table 和样本记录:

CREATE TABLE t1 (id NUMBER, VENDOR VARCHAR2, HOURS VARCHAR2);

INSERT INTO t1 (id, vendor, hours)
VALUES 
(1001, 'ABC', 'Monday, 07:00AM–12AM, Tuesday, 10:30AM–12AM, Wednesday, 10:30AM–12AM, Thursday, 10:30AM–12AM, Friday, 10:30AM–12AM, Saturday, 10:30AM–12AM, Sunday, 10:30AM–12AM'),
(1002, 'DEF', 'Monday, 08:00AM–01PM, Tuesday, 08:00AM–01PM, Wednesday, 08:00AM–01PM, Thursday, 08:00AM–01PM, Friday, 08:00AM–01PM, Saturday, 10:30AM–12AM, Sunday, 10:30AM–01PM'),
(1003, 'GHE', 'Monday, 09:00AM–02PM, Tuesday, 09:00AM–02PM, Wednesday, 09:00AM–02PM, Thursday, 09:00AM–02PM, Friday, 09:00AM–02PM, Saturday, 10:30AM–12AM, Sunday, 10:30AM–12AM'),
(1004, 'IJK', 'Monday, 10:00AM–03PM, Tuesday, 10:00AM–03PM, Wednesday, 10:00AM–03PM, Thursday, 10:00AM–03PM, Friday, 10:00AM–02PM, Saturday, 10:30AM–12AM, Sunday, 10:30AM–12AM'),
(1005, 'LMN', 'Monday, 10:30AM–04PM, Tuesday, 10:30AM–12AM, Wednesday, 10:30AM–12AM, Thursday, 10:30AM–12AM, Friday, 10:30AM–02PM, Saturday, 10:30AM–12AM, Sunday, 10:30AM–12AM');
WITH days_of_week AS (
  SELECT * FROM (
    SELECT column1, ROW_NUMBER() OVER (ORDER BY1) AS row_number
    FROM VALUES
        ('Monday'), ('10:30AM–12AM'), ('Tuesday'), ('10:30AM–12AM'), ('Wednesday'), ('10:30AM–12AM'), ('Thursday'), ('10:30AM–12AM'), ('Friday'), ('10:30AM–12AM'), ('Saturday'), ('10:30AM–12AM'), ('Sunday'), ('10:30AM–12AM')
    )
  WHERE row_number % 2 = 1 ),
hours_open AS (
  SELECT * FROM(
    SELECT column1, ROW_NUMBER() OVER (ORDER BY1) AS row_number
    FROM VALUES
        ('Monday'), ('10:30AM–12AM'), ('Tuesday'), ('10:30AM–12AM'), ('Wednesday'), ('10:30AM–12AM'), ('Thursday'), ('10:30AM–12AM'), ('Friday'), ('10:30AM–12AM'), ('Saturday'), ('10:30AM–12AM'), ('Sunday'), ('10:30AM–12AM')
    )
  WHERE row_number % 2 = 0)
SELECT  d.column1 AS Day, h.column1 AS Schedule 
FROM days_of_week d
INNER JOIN hours_open h
ON d.row_number = h.row_number-1;
CREATE TABLE DEV.EDW.t1 (id NUMBER, VENDOR VARCHAR2, HOURS VARCHAR2);

INSERT INTO DEV.EDW.t1 (id, vendor, hours)
VALUES 
(1001, 'ABC', 'Monday, 07:00AM–12AM, Tuesday, 10:30AM–12AM, Wednesday, 10:30AM–12AM, Thursday, 10:30AM–12AM, Friday, 10:30AM–12AM, Saturday, 10:30AM–12AM, Sunday, 10:30AM–12AM'),
(1002, 'DEF', 'Monday, 08:00AM–01PM, Tuesday, 08:00AM–01PM, Wednesday, 08:00AM–01PM, Thursday, 08:00AM–01PM, Friday, 08:00AM–01PM, Saturday, 10:30AM–12AM, Sunday, 10:30AM–01PM'),
(1003, 'GHE', 'Monday, 09:00AM–02PM, Tuesday, 09:00AM–02PM, Wednesday, 09:00AM–02PM, Thursday, 09:00AM–02PM, Friday, 09:00AM–02PM, Saturday, 10:30AM–12AM, Sunday, 10:30AM–12AM'),
(1004, 'IJK', 'Monday, 10:00AM–03PM, Tuesday, 10:00AM–03PM, Wednesday, 10:00AM–03PM, Thursday, 10:00AM–03PM, Friday, 10:00AM–02PM, Saturday, 10:30AM–12AM, Sunday, 10:30AM–12AM'),
(1005, 'LMN', 'Monday, 10:30AM–04PM, Tuesday, 10:30AM–12AM, Wednesday, 10:30AM–12AM, Thursday, 10:30AM–12AM, Friday, 10:30AM–02PM, Saturday, 10:30AM–12AM, Sunday, 10:30AM–12AM');

SELECT * FROM DEV.EDW.t1;

SELECT Id,Vendor,DAY,SCHEDULE FROM (
Select  src.id,src.Vendor
       ,CASE WHEN Index%2=1 THEN VALUE END AS DAY
       ,LEAD(VALUE) OVER(PARTITION BY SEQ ORDER BY INDEX) AS SCHEDULE
From (SELECT ID,VENDOR,HOURS FROM DEV.EDW.t1 ) src, table(strtok_split_to_table(src.HOURS,','))
) out WHERE DAY IS NOT NULL
ORDER BY ID,Vendor
;

啊,很有趣,将输入调整为每个 day/hour 只有一个逗号,然后 split_to_table 然后通过调整拆分以快速获胜,有趣!

因此,将大量样本数据转化为 CTE:

WITH cte_table_data as (
    SELECT * FROM VALUES 
        (1001, 'ABC', 'Monday, 07:00AM–12AM, Tuesday, 10:30AM–12AM, Wednesday, 10:30AM–12AM, Thursday, 10:30AM–12AM, Friday, 10:30AM–12AM, Saturday, 10:30AM–12AM, Sunday, 10:30AM–12AM'),
        (1002, 'DEF', 'Monday, 08:00AM–01PM, Tuesday, 08:00AM–01PM, Wednesday, 08:00AM–01PM, Thursday, 08:00AM–01PM, Friday, 08:00AM–01PM, Saturday, 10:30AM–12AM, Sunday, 10:30AM–01PM'),
        (1003, 'GHE', 'Monday, 09:00AM–02PM, Tuesday, 09:00AM–02PM, Wednesday, 09:00AM–02PM, Thursday, 09:00AM–02PM, Friday, 09:00AM–02PM, Saturday, 10:30AM–12AM, Sunday, 10:30AM–12AM'),
        (1004, 'IJK', 'Monday, 10:00AM–03PM, Tuesday, 10:00AM–03PM, Wednesday, 10:00AM–03PM, Thursday, 10:00AM–03PM, Friday, 10:00AM–02PM, Saturday, 10:30AM–12AM, Sunday, 10:30AM–12AM'),
        (1005, 'LMN', 'Monday, 10:30AM–04PM, Tuesday, 10:30AM–12AM, Wednesday, 10:30AM–12AM, Thursday, 10:30AM–12AM, Friday, 10:30AM–02PM, Saturday, 10:30AM–12AM, Sunday, 10:30AM–12AM')
    t(id, vendor, hours)
)

和这个SQL

select 
    c.id, 
    c.vendor,
    trim(split_part(v.value,'|',1)) as day,
    trim(split_part(v.value,'|',2)) as SCHEDULE
from cte_table_data as c
    ,table(split_to_table(replace(c.hours,'y,','y|'), ',')) v
order by v.seq, v.index;
ID VENDOR DAY SCHEDULE
1001 ABC Monday 07:00AM–12AM
1001 ABC Tuesday 10:30AM–12AM
1001 ABC Wednesday 10:30AM–12AM
1001 ABC Thursday 10:30AM–12AM
1001 ABC Friday 10:30AM–12AM
1001 ABC Saturday 10:30AM–12AM
1001 ABC Sunday 10:30AM–12AM
1002 DEF Monday 08:00AM–01PM
1002 DEF Tuesday 08:00AM–01PM
1002 DEF Wednesday 08:00AM–01PM
1002 DEF Thursday 08:00AM–01PM
1002 DEF Friday 08:00AM–01PM
1002 DEF Saturday 10:30AM–12AM
1002 DEF Sunday 10:30AM–01PM
1003 GHE Monday 09:00AM–02PM
1003 GHE Tuesday 09:00AM–02PM
1003 GHE Wednesday 09:00AM–02PM
1003 GHE Thursday 09:00AM–02PM
1003 GHE Friday 09:00AM–02PM
1003 GHE Saturday 10:30AM–12AM
1003 GHE Sunday 10:30AM–12AM
1004 IJK Monday 10:00AM–03PM
1004 IJK Tuesday 10:00AM–03PM
1004 IJK Wednesday 10:00AM–03PM
1004 IJK Thursday 10:00AM–03PM
1004 IJK Friday 10:00AM–02PM
1004 IJK Saturday 10:30AM–12AM
1004 IJK Sunday 10:30AM–12AM
1005 LMN Monday 10:30AM–04PM
1005 LMN Tuesday 10:30AM–12AM
1005 LMN Wednesday 10:30AM–12AM
1005 LMN Thursday 10:30AM–12AM
1005 LMN Friday 10:30AM–02PM
1005 LMN Saturday 10:30AM–12AM
1005 LMN Sunday 10:30AM–12AM