查询以使数据分组

时间:2012-08-18 06:41:33

标签: sql

我有一些像这样的数据

datetime              value
2012-01-01 16:21:52     6
2012-01-01 16:22:02     5
2012-01-01 16:22:12     2
2012-01-01 16:22:22     3
2012-01-01 16:22:32     6
2012-01-01 16:22:42     9
2012-01-01 16:22:52     1
2012-01-01 16:23:02     3
2012-01-01 16:23:12     16
2012-01-01 16:24:02     7
2012-01-01 16:24:12     2
2012-01-01 16:24:22     6
2012-01-01 16:24:32     1
2012-01-01 16:24:42     8
2012-01-01 16:24:52     12
2012-01-01 16:25:02     15
2012-01-01 16:25:12     41
2012-01-01 16:25:22     29
2012-01-01 16:25:32     6
2012-01-01 16:25:42     6
2012-01-01 16:25:52     20
2012-01-01 16:26:02     10
2012-01-01 16:26:12     16
2012-01-01 16:26:22     14
2012-01-01 16:26:32     10
2012-01-01 16:26:42     6
2012-01-01 16:26:52     9
2012-01-01 16:27:02     7
2012-01-01 16:27:12     7
2012-01-01 16:27:22     17

我需要一个查询来将数据分组,其值为< 10 我需要下面的结果

from                     to                   count
2012-01-01 16:21:52     2012-01-01 16:23:02     8
2012-01-01 16:24:02     2012-01-01 16:24:42     5
2012-01-01 16:25:32     2012-01-01 16:25:42     2
2012-01-01 16:26:42     2012-01-01 16:27:12     4

我想知道如何在“值”小于10的组中获取数据的范围和数量

2 个答案:

答案 0 :(得分:2)

如果您可以访问ROW_NUMBER(),则可以更简单地解决这个问题 - 这存在于更新版本的Oracle,SQL Server等中 - 它在MySQL中不存在

请确认您使用的是哪个RDBMS。

如果您确实可以访问ROW_NUMBER()这是一种方法......

WITH
  gaps_and_islands AS
(
  SELECT
    *,
    CASE WHEN value < 10 THEN 1 ELSE 0 END as is_island,
    ROW_NUMBER() OVER (                                                    ORDER BY value) AS land_level,
    ROW_NUMBER() OVER (PARTITION BY CASE WHEN value < 10 THEN 1 ELSE 0 END ORDER BY value) AS water_level
  FROM
    yourData
)
SELECT
  is_island,
  MIN(datetime_field)    AS from_datetime,
  MAX(datetime_field)    AS to_datetime,
  COUNT(*)               AS count_of_rows
FROM
  gaps_and_islands
GROUP BY
  is_island,
  (land_level - water_level)
ORDER BY
  MIN(datetime_field)

这是第一次看到它时的一种非常新颖的方法。所以我会通过附加到您的数据向您展示它是如何工作的......

datetime              value   land_level  water_level  (land_level-water_level)
2012-01-01 16:21:52     6          1             1                0
2012-01-01 16:22:02     5          2             2                0
2012-01-01 16:22:12     2          3             3                0
2012-01-01 16:22:22     3          4             4                0
2012-01-01 16:22:32     6          5             5                0
2012-01-01 16:22:42     9          6             6                0
2012-01-01 16:22:52     1          7             7                0
2012-01-01 16:23:02     3          8             8                0
2012-01-01 16:23:12     16         9            (1)              (8)
2012-01-01 16:24:02     7         10             9                1
2012-01-01 16:24:12     2         11            10                1
2012-01-01 16:24:22     6         12            11                1
2012-01-01 16:24:32     1         13            12                1
2012-01-01 16:24:42     8         14            13                1
2012-01-01 16:24:52     12        15            (2)             (13)
2012-01-01 16:25:02     15        16            (3)             (13)
2012-01-01 16:25:12     41        17            (4)             (13)
2012-01-01 16:25:22     29        18            (5)             (13)
2012-01-01 16:25:32     6         19            14                5
2012-01-01 16:25:42     6         20            15                5
2012-01-01 16:25:52     20        21            (6)             (15)
2012-01-01 16:26:02     10        22            (7)             (15)
2012-01-01 16:26:12     16        23            (8)             (15)
2012-01-01 16:26:22     14        24            (9)             (15)
2012-01-01 16:26:32     10        25           (10)             (15)
2012-01-01 16:26:42     6         26            16               10
2012-01-01 16:26:52     9         27            17               10
2012-01-01 16:27:02     7         28            18               10
2012-01-01 16:27:12     7         29            19               10
2012-01-01 16:27:22     17        30           (11)             (19)

land_level只为每个连续记录提供从1开始的行ID。

water_level是相同的,只有两个列表(分区) - value< 10的所有记录从1开始获取自己的顺序ID - value>= 10的所有记录从1开始获取自己的连续ID。

(这可以更容易看到,因为我把water_level放在value所在的>= 10

然后,当你从另一个拿走一个时,会发生什么。您可以获得在同一间隙或岛屿中彼此相邻的所有记录的唯一标识。

答案 1 :(得分:-1)

select
from = min(datetime),
to = max(datetime),
count = count(*)
from table_name
where value < 10
group by value

有一点需要注意,这些列名可能不起作用,因为这些是DB关键字。