【问题标题】:ORACLE SELECT GROUP BY + something that I don't knowORACLE SELECT GROUP BY + 我不知道的东西
【发布时间】:2013-01-25 11:52:09
【问题描述】:

我在 ORACLE 数据库中有一个表,详细信息如下:

--------------------------------------------
|                  FRUITS                  |
--------------------------------------------
| FRUIT_NAME | GROWTH_TIME | GROWTH_PLACE  |
--------------------------------------------
|      melon |        0600 |        shelf1 |
|      melon |        0630 |        shelf1 |
|      melon |        0700 |        shelf1 |
|      melon |        0730 |        shelf1 |
|      melon |        0800 |        shelf1 |

|     orange |        0600 |        shelf5 |
|     orange |        0630 |        shelf5 |
|     orange |        0700 |        shelf5 |
|     orange |        0730 |        shelf5 |
|     orange |        0800 |        shelf5 |
|     orange |        0830 |        shelf5 |
|     orange |        0900 |        shelf5 |
|     orange |        0930 |        shelf5 |
|     orange |        1000 |        shelf5 |

|     orange |        1200 |        shelf5 |
|     orange |        1230 |        shelf5 |
|     orange |        1300 |        shelf5 |
|     orange |        1330 |        shelf5 |
|     orange |        1400 |        shelf5 |

|      apple |        0600 |        shelf3 |
|      apple |        0630 |        shelf3 |
|      apple |        0700 |        shelf3 |
|      apple |        0730 |        shelf3 |
|      apple |        0800 |        shelf3 |
--------------------------------------------

我希望得到如下结果:

--------------------------------------------
| FRUIT_NAME | GROWTH_TIME | GROWTH_PLACE  |
--------------------------------------------
|      melon |   0600-0800 |        shelf1 |

|     orange |   0600-1000 |        shelf5 |
|     orange |   1200-1400 |        shelf5 |

|      apple |   0600-0800 |        shelf3 |


或像这些:

-------------------------------------------------------------------
| FRUIT_NAME | GROWTH_START_TIME | GROWTH_END_TIME | GROWTH_PLACE |
-------------------------------------------------------------------
|      melon |              0600 |            0800 |       shelf1 |

|     orange |              0600 |            1000 |       shelf5 |
|     orange |              1200 |            1400 |       shelf5 |

|      apple |              0600 |            0800 |       shelf3 |


ORANGE 表壳有一个小间隙(在 1000 和 1400 之间),这仍然是同一个架子,但时间上的差距很小。它发生了,但我不知道如何解决这个问题。

【问题讨论】:

    标签: oracle select group-by max min


    【解决方案1】:

    您可以通过分析解决这个问题:

    SQL> select fruit_name, min(growth_time) || '-' || max(growth_time) growth_time, growth_place
      2    from (select fruit_name, growth_place, growth_time,
      3                 max(grp) over(partition by fruit_name, growth_place order by growth_time) grp
      4             from (select fruit_name, growth_time, growth_place,
      5                          case
      6                            when to_date(lag(growth_time, 1)
      7                                   over(partition by fruit_name, growth_place order by growth_time), 'hh24mi')
      8                                 < to_date(growth_time, 'hh24mi') - (30/1440)
      9                            then
     10                              row_number() over(partition by fruit_name, growth_place order by growth_time)
     11                            when row_number() over(partition by fruit_name, growth_place order by growth_time) = 1
     12                            then
     13                              1
     14                          end grp
     15                      from fruits))
     16   group by fruit_name, growth_place, grp
     17   order by fruit_name, growth_time
     18  /
    
    FRUIT_ GROWTH_TIME                              GROWTH
    ------ ---------------------------------------- ------
    apple  0600-0800                                shelf3
    melon  0600-0800                                shelf1
    orange 0600-1000                                shelf5
    orange 1200-1400                                shelf5
    

    即首先,我们将结果集分成组,其中组被定义为给定水果/货架的连续日期。

    我们通过检查前一个日期并查看它是否 来做到这一点

    lag(growth_time, 1) over (partition by fruit_name, growth_place order by growth_time)
    

    由此我们可以得出前一行比该行早 30 分钟的组:

    SQL> select fruit_name, growth_time, growth_place,
      2         case
      3           when to_date(lag(growth_time, 1)
      4                over(partition by fruit_name, growth_place order by growth_time), 'hh24mi')
      5                < to_date(growth_time, 'hh24mi') - (30/1440)
      6           then
      7             row_number() over(partition by fruit_name, growth_place order by growth_time)
      8           when row_number() over(partition by fruit_name, growth_place order by growth_time) = 1
      9           then
     10             1
     11         end grp
     12    from fruits;
    
    FRUIT_ GROW GROWTH        GRP
    ------ ---- ------ ----------
    apple  0600 shelf3          1
    apple  0630 shelf3
    apple  0700 shelf3
    apple  0730 shelf3
    apple  0800 shelf3
    melon  0600 shelf1          1
    melon  0630 shelf1
    melon  0700 shelf1
    melon  0730 shelf1
    melon  0800 shelf1
    orange 0600 shelf5          1
    orange 0630 shelf5
    orange 0700 shelf5
    orange 0730 shelf5
    orange 0800 shelf5
    orange 0830 shelf5
    orange 0900 shelf5
    orange 0930 shelf5
    orange 1000 shelf5
    orange 1200 shelf5         10
    orange 1230 shelf5
    orange 1300 shelf5
    orange 1330 shelf5
    orange 1400 shelf5
    

    现在我们只需使用 max() 分析将组分配给每一行:

    SQL> select fruit_name, growth_place, growth_time,
      2         max(grp) over(partition by fruit_name, growth_place order by growth_time) grp
      3    from (select fruit_name, growth_time, growth_place,
      4                 case
      5                 when to_date(lag(growth_time, 1)
      6                        over(partition by fruit_name, growth_place order by growth_time), 'hh24mi')
      7                      < to_date(growth_time, 'hh24mi') - (30/1440)
      8                 then
      9                   row_number() over(partition by fruit_name, growth_place order by growth_time)
     10                 when row_number() over(partition by fruit_name, growth_place order by growth_time) = 1
     11                 then
     12                   1
     13               end grp
     14          from fruits);
    
    FRUIT_ GROWTH GROW        GRP
    ------ ------ ---- ----------
    apple  shelf3 0600          1
    apple  shelf3 0630          1
    apple  shelf3 0700          1
    apple  shelf3 0730          1
    apple  shelf3 0800          1
    melon  shelf1 0600          1
    melon  shelf1 0630          1
    melon  shelf1 0700          1
    melon  shelf1 0730          1
    melon  shelf1 0800          1
    orange shelf5 0600          1
    orange shelf5 0630          1
    orange shelf5 0700          1
    orange shelf5 0730          1
    orange shelf5 0800          1
    orange shelf5 0830          1
    orange shelf5 0900          1
    orange shelf5 0930          1
    orange shelf5 1000          1
    orange shelf5 1200         10
    orange shelf5 1230         10
    orange shelf5 1300         10
    orange shelf5 1330         10
    orange shelf5 1400         10
    

    现在剩下的就是GRP 上的最后一组,以获得最终答案。

    【讨论】:

    • 这是一项很棒的工作!非常感谢!一切都很好(所有 3 个步骤),FIDDLE 不会说谎:)
    【解决方案2】:

    您可以使用LEAD函数,使用按GROWTH_TIME排序的FRUIT_NAME分区,得到下一条记录的GROWTH_TIME,与当前的比较就可以知道有没有差距。

    SELECT FRUIT_NAME , MIN(GROWTH_TIME ) || '-' || MAX(GROWTH_TIME ), GROWTH FROM (
        SELECT FRUIT_NAME , GROWTH_TIME , 
        NVL(lead (GROWTH_TIME ) over (partition by FRUIT_NAME  order by GROWTH_TIME ) -   GROWTH_TIME , 0) as gap
        FROM FRUITS
      )
    GROUP BY FRUIT_NAME, gap
    HAVING (gap <= 70)
    

    【讨论】:

    • 请更正您的查询,有问题。这不是我需要的。我的意思是结果。
    • @@Miguel Matos:你的结果和我的不一样,看FIDDLE
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-07
    • 2011-08-14
    相关资源
    最近更新 更多