【问题标题】:Min/Max timestamp of a slow changing dimension缓慢变化维度的最小/最大时间戳
【发布时间】:2019-01-01 17:48:59
【问题描述】:

我对我需要的 SQL (Redshift) 查询有一些想法。所以基本上,我有下表

userid | timestamp           | fruit
  1    | 2018-12-10T14:46:50 | banana 
  1    | 2018-12-10T15:46:50 | banana
  1    | 2018-12-10T16:46:50 | apple
  1    | 2018-12-10T17:46:50 | banana

是否有可能想出一个包含以下信息的新表

userid | start               | end                 | fruit
  1    | 2018-12-10T14:46:50 | 2018-12-10T16:46:50 | banana 
  1    | 2018-12-10T16:46:50 | 2018-12-10T17:46:50 | apple
  1    | 2018-12-10T17:46:50 |                     | banana

显示用户保留他最喜欢的水果选择的时间范围。

提前致谢!

D

【问题讨论】:

    标签: sql amazon-redshift gaps-and-islands


    【解决方案1】:

    这是一个典型的gaps and islands问题,laglead解析函数可能使用如下:

    with fruits(userid,timestamp,fruit) as (
    values 
      (1,'2018-12-10T14:46:50','banana'), 
      (1,'2018-12-10T15:46:50','banana'),
      (1,'2018-12-10T16:46:50','apple'),
      (1,'2018-12-10T17:46:50','banana')    
    )
     select userid, min(timestamp) as start, max(ld) as end, fruit
       from
       (
            select f2.*,
                   sum(case when lg = fruit then 0 else 1 end) over
                             (partition by userid, fruit order by timestamp) sm
              from
              (
                 select f1.*,
                        lead(timestamp) over (partition by userid order by timestamp) as ld,
                        lag(fruit) over (partition by userid order by timestamp) as lg
                   from fruits f1
              ) f2
       ) f    
      group by userid, fruit, sm
      order by start;
    
    userid     start                    end           fruit
    ------- ------------------- -------------------   ------
      1     2018-12-10T14:46:50 2018-12-10T16:46:50   banana
      1     2018-12-10T16:46:50 2018-12-10T17:46:50   apple
      1     2018-12-10T17:46:50         NULL          banana
    

    Rextester Demo

    【讨论】:

    • 不幸的是,当用户重新选择相同的收藏夹两次时,这将不起作用,因为该组允许每个结果单行,并且 sm 可以相同两次
    • @SunSatION 我在演示中显示此查询有效。请分享示例以说明您的确切含义。
    【解决方案2】:

    架构 (MySQL v8.0)

    CREATE TABLE t1 (
      `userid` INTEGER,
      `timestamp` VARCHAR(19),
      `fruit` VARCHAR(6)
    );
    
    INSERT INTO t1
      (`userid`, `timestamp`, `fruit`)
    VALUES
      ('1', '2018-12-10T14:46:50', 'banana'),
      ('1', '2018-12-10T15:46:50', 'banana'),
      ('1', '2018-12-10T16:46:50', 'apple'),
      ('1', '2018-12-10T17:46:50', 'banana');
    

    查询 #1

    如果您不介意连续水果的多个记录,那么简单的方法

    select userid, fruit, timestamp `start`, 
      lead(timestamp) over (order by timestamp) `end`
    from t1;
    
    | userid | fruit  | start               | end                 |
    | ------ | ------ | ------------------- | ------------------- |
    | 1      | banana | 2018-12-10T14:46:50 | 2018-12-10T15:46:50 |
    | 1      | banana | 2018-12-10T15:46:50 | 2018-12-10T16:46:50 |
    | 1      | apple  | 2018-12-10T16:46:50 | 2018-12-10T17:46:50 |
    | 1      | banana | 2018-12-10T17:46:50 |                     |
    

    或者 查询 #2

    SELECT t2.* 
    FROM   ( 
                    SELECT   userid, 
                             fruit, 
                             timestamp `tstart`, 
                             CASE 
                                      WHEN fruit = Lead(fruit) over(ORDER BY timestamp) THEN lead(timestamp, 2) over ( ORDER BY timestamp)
                                      ELSE lead(timestamp, 1) over ( ORDER BY timestamp) 
                             end `tend`, 
                             CASE 
                                      WHEN fruit = lag(fruit) over (ORDER BY timestamp) THEN 1 
                                      ELSE 0 
                             end del 
                    FROM     t1 ) t2 
    WHERE  del = 0;
    
    
    | userid | fruit  | tstart              | tend                | del |
    | ------ | ------ | ------------------- | ------------------- | --- |
    | 1      | banana | 2018-12-10T14:46:50 | 2018-12-10T16:46:50 | 0   |
    | 1      | apple  | 2018-12-10T16:46:50 | 2018-12-10T17:46:50 | 0   |
    | 1      | banana | 2018-12-10T17:46:50 |                     | 0   |
    

    View on DB Fiddle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-03
      • 2013-08-10
      • 1970-01-01
      • 1970-01-01
      • 2020-11-09
      • 2011-05-08
      • 2015-07-22
      • 2018-02-18
      相关资源
      最近更新 更多