【问题标题】:Select the entire datetime after grouping by date (without time)按日期分组后选择整个日期时间(无时间)
【发布时间】:2014-06-27 08:26:24
【问题描述】:

我有一个表,它每 15 分钟计算一次用户数,然后将该数字与数据库中的时间一起记录。条目如下所示:

users1| users2 |Time_Stamp
15    | 0      |2014-03-15 13:00:00.000
35    | 15     |2014-03-15 13:15:00.000
12    | 55     |2014-03-15 13:30:00.000
2     | 115    |2014-03-15 13:45:00.000
0     | 5      |2014-03-15 14:00:00.000
2     | 115    |2014-03-16 12:45:00.000
123   | 15     |2014-03-16 13:00:00.000

我需要做的是选择特定时间段内的最大用户数(对于特定组),在这种情况下,一天分组在每天的午夜之间,然后显示甚至发生的确切时间。

在上面的例子中,我想要的输出是:

max users1 |Time_Stamp
35         |2014-03-15 13:15:00.000
123        |2014-03-16 13:00:00.000

很容易获得每天的最大值,而忽略时间戳。

select cast(time_stamp as date) as "time", max(users1) as "c"
from Counts
where users1 > 0
group by cast(time_stamp as date)

这给了

max users1 |Time_Stamp
35         |2014-03-15
123        |2014-03-16

换句话说,我需要一天的最大用户数,以及它发生的时间。

我已经解决了这个问题,但它看起来非常糟糕。下面是我的解决方案。有没有人可以帮我想出更好的方法?

另外,我想实现这些读数不仅每天,而且每小时或每 6 小时。

select users1, TIME_STAMP
from counts c
    inner join (
        select 
            cast(abc.time as datetime) as "day_start", 
            dateadd(day,+1,cast(abc.time as datetime)) as "day_end",
            abc.c as "day_max"
        from (
            select cast(time_stamp as date) as "time", max(users1) as "c"
            from Counts
            where users1 > 0
            group by cast(time_stamp as date)
            ) abc
        ) t
        on t.day_max = c.users1
where c.TIME_STAMP >= t.day_start
    and c.TIME_STAMP < t.day_end
order by c.TIME_STAMP desc

编辑:有时,最大值不是唯一的。我希望能够在最大值出现时显示每个时间戳。

示例,然后是预期输出,如下。

users1| TIME_STAMP
137 | 2014-06-21 11:15:00.000
137 | 2014-06-21 11:00:00.000
137 | 2014-06-21 10:45:00.000
137 | 2014-06-21 10:30:00.000
137 | 2014-06-21 10:15:00.000
136 | 2014-06-21 10:00:00.000
136 | 2014-06-21 09:45:00.000
136 | 2014-06-21 09:30:00.000
136 | 2014-06-21 09:15:00.000
136 | 2014-06-21 09:00:00.000

users1| TIME_STAMP
137 | 2014-06-21 11:15:00.000
137 | 2014-06-21 11:00:00.000
137 | 2014-06-21 10:45:00.000
137 | 2014-06-21 10:30:00.000
137 | 2014-06-21 10:15:00.000

【问题讨论】:

    标签: sql sql-server refactoring


    【解决方案1】:

    使用row_number() 代替group by

    select c.*
    from (select c.*,
                row_number() over (partition by cast(time_stamp as date) order by users1 desc) as seqnum
          from counts c
         ) c
    where seqnum = 1;
    

    这将返回每天具有最大值的行。

    编辑:

    如果您希望所有行都具有最大值,请使用 rank()dense_rank() 而不是 row_number()

    select c.*
    from (select c.*,
                dense_rank() over (partition by cast(time_stamp as date) order by users1 desc) as seqnum
          from counts c
         ) c
    where seqnum = 1;
    

    【讨论】:

    • 这非常有效,但我的问题的一部分我需要更清楚。最大值不是唯一的,因此可能有多次出现最大值。当我使用你的功能时,它只会选择一个。我会更新我的问题以使这一点更清楚。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 2014-03-28
    • 2017-01-30
    相关资源
    最近更新 更多