【问题标题】:group by date and show the values of X(column) which depends on min time of that date and max time of that date in 1 row按日期分组并显示 X(column) 的值,这取决于该日期的最小时间和该日期的最大时间在 1 行中
【发布时间】:2020-12-02 07:31:44
【问题描述】:

我有这样的桌子

id  u_id     date       time      x
---|-----|------------|--------|-----
1  | 1   | 20200806   | 0900   | 60 
2  | 2   | 20200806   | 0905   | 60 
3  | 3   | 20200806   | 0910   | 61 
4  | 1   | 20200806   | 1015   | 62 
5  | 1   | 20200806   | 1830   | 61 
6  | 3   | 20200807   | 0915   | 61 
7  | 1   | 20200807   | 0920   | 62 
8  | 2   | 20200807   | 1820   | 63 
9  | 1   | 20200807   | 1835   | 59 

我想 按日期分组 哪个用户有 u_id的id =1 并获得第一次和 x 的值 并获得 x 的最后时间和值 在同一行

应该是这样的

   date       firstTime  firstX   lastTime   lastX
   -----------|----------|--------|----------|----------
   20200806   |   0900   |   60   |   1830   | 61
   20200807   |   0920   |   62   |   1835   | 59

我试过的

select
            p.created_date as date,
            min(p.created_time) as firstTime,
            max(p.created_time) as lastTime,
from
     passes as p
where
      p.id=1
group by p.created_date;

但我无法获取 xs 的值。

行:

【问题讨论】:

    标签: php sql postgresql


    【解决方案1】:

    一种方法使用条件聚合:

    select p.created_date as date,
           min(p.created_time) as firstTime,
           max(p.created_time) as lastTime,
           max(case when seqnum = 1 then x end) as first_x,
           max(case when seqnum_desc = 1 then x end) as last_x,
    from (select p.*,
                 row_number() over (partition by id order by created_time) as seqnum,
                 row_number() over (partition by id order by created_time desc) as seqnum_desc
          from passes p
         ) p
    where p.id=1
    group by p.created_date;
    

    您还可以将条件聚合表述为:

           max(x) filter where (seqnum = 1) as first_x,
           max(x) filter where (seqnum_desc = 1) as last_x,
    

    另一种方法使用数组:

    select p.created_date as date,
           min(p.created_time) as firstTime,
           max(p.created_time) as lastTime,)
           (array_agg(p.x order by p.created_date asc))[1] as first_x,
           (array_agg(p.x order by p.created_date desc))[1] as last_x
    from passes p
    where p.id = 1
    group by p.created_date;
    

    【讨论】:

    • min(当 seqnum = 1 然后温度结束的情况)作为 first_x 然后工作。非常感谢!
    • 布尔列呢?
    • @BertanCakici 。 . .您需要使用bool_or()bool_and()。或者对于一个常见的表达方式(array_agg(x) filter (where seqnum = 1))[1]
    【解决方案2】:

    我会使用first_value()last_value() 窗口函数来实现:

    select distinct 
           "date", 
           first_value(time) over w as first_time,
           first_value(x) over w as first_x,
           last_value(time) over w as last_time,
           last_value(x) over w as last_x
      from passes
     where u_id = 1
    window w as (partition by u_id
                     order by date
              rows between unbounded preceding
                       and unbounded following);
    

    Working Fiddle Here

    【讨论】:

      【解决方案3】:

      我能够通过创建子查询来重现您的结果。子查询按日期分组值并返回第一次和最后一次。

      通过确定日期、第一次和最后一次,我进行了两次连接,一次获取 firstX,另一次获取 lastX。

      通过使用 mySQL 作为引擎,我在 http://sqlfiddle.com/ 上执行了这些步骤:

      构建架构:

      CREATE TABLE passes
          (`id` int, `u_id` int, `date` int, `time` int, `x` int)
      ;
      INSERT INTO passes
          (`id`, `u_id`, `date`, `time`, `x`)
      VALUES
          (1, 1, 20200806, 0900, 60),
          (2, 2, 20200806, 0905, 60),
          (3, 3, 20200806, 0910, 61),
          (4, 1, 20200806, 1015, 62),
          (5, 1, 20200806, 1830, 61),
          (6, 3, 20200807, 0915, 61),
          (7, 1, 20200807, 0920, 62),
          (8, 2, 20200807, 1820, 63),
          (9, 1, 20200807, 1835, 59)
      ;
      

      MySQL 查询:

      Select SUB1.TheDate,SUB1.firstTime,x1.x as firstX,SUB1.lastTime,x2.x as lastX from 
      (select
            passes.date as TheDate,
            min(passes.time) as firstTime,
            max(passes.time) as lastTime
      from passes
      where
        passes.u_id = 1
      group by passes.date) AS SUB1
      
      join passes as x1 
      on x1.date = SUB1.TheDate
      and x1.time = SUB1.firstTime
      
      join passes as x2 
      on x2.date = SUB1.TheDate
      and x2.time = SUB1.lastTime
      

      结果如下所示:

      
      TheDate     firstTime   firstX  lastTime    lastX
      20200806    900         60      1830        61
      20200807    920         62      1835        59
      
      

      【讨论】:

        猜你喜欢
        • 2015-12-12
        • 2022-01-18
        • 2023-01-15
        • 1970-01-01
        • 2020-02-12
        • 2016-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多