AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 193347
Accepted
GWR
GWR
Asked: 2017-12-18 08:37:55 +0800 CST2017-12-18 08:37:55 +0800 CST 2017-12-18 08:37:55 +0800 CST

使用可以跨越一天的日期时间戳对会话进行分组

  • 772

我正在处理具有随时间回收的会话 ID 值的数据(确切地说是来自 IIS 的 asp 会话 ID)。

我试图给他们一个序列,这样 ASP_SESSION_ID 的每个实例就不会组合在一起。

例如,数据看起来像这样。相同的会话 ID,在 2016 年 8 月使用,然后在 2017 年 3 月再次使用。

DTTM                        SESSION_ID
2016-08-29 14:24:28.450     297692378
2017-04-13 23:54:53.760     297692378
2017-04-13 23:59:53.477     297692378
2017-04-14 00:04:52.897     297692378
2017-04-14 00:04:53.790     297692378

起初我想只按日期分组(在 DAY 级别),但对于上面的示例,请注意会话 ID 的第二个实例是如何跨越午夜的。这将导致第三组,而实际上是同一个会话。

因此,如果我能正确地对它们进行排名,那将是:

DTTM                        SESSION_ID      RANK
2016-08-29 14:24:28.450     297692378       1
2017-04-13 23:54:53.760     297692378       2
2017-04-13 23:59:53.477     297692378       2
2017-04-14 00:04:52.897     297692378       2
2017-04-14 00:04:53.790     297692378       2

此处,当自上次请求以来超过 20 分钟后,ASP_SESSION_ID 应被视为会话的新实例。

那么,随着时间的推移,我如何对相同的 ASP_SESSION_ID 进行分组或对其进行不同的排名?例如,如果该 ASP_SESSION_ID 的下一个请求距离上一个请求 > 20 分钟,则将其分组/排名不同?

我只是不确定如何解决这个问题。

以下是生成上述数据的一些语句:

CREATE TABLE #TEST
(
DTTM DATETIME, 
SESSION_ID INT
)

INSERT INTO #TEST (DTTM, SESSION_ID)
select '2016-08-29 14:24:28.450', 297692378 union
select '2017-04-13 23:54:53.760', 297692378 union
select '2017-04-13 23:59:53.477', 297692378 union
select '2017-04-14 00:04:52.897', 297692378 union
select '2017-04-14 00:04:53.790', 297692378 
sql-server t-sql
  • 1 1 个回答
  • 104 Views

1 个回答

  • Voted
  1. Best Answer
    McNets
    2017-12-18T10:13:10+08:002017-12-18T10:13:10+08:00
    CREATE TABLE TEST
    (
    DTTM DATETIME, 
    SESSION_ID INT
    )
    
    INSERT INTO TEST (DTTM, SESSION_ID)
    select '2016-08-29 14:24:28.450', 297692378 union
    select '2017-04-13 23:54:53.760', 297692378 union
    select '2017-04-13 23:59:53.477', 297692378 union
    select '2017-04-14 00:04:52.897', 297692378 union
    select '2017-04-14 00:04:53.790', 297692378 union
    select '2017-04-14 00:44:53.790', 297692378
    GO
    

    首先,我添加了一条新记录,只是为了检查它是否运行了 20 多分钟。

    select '2017-04-14 00:44:53.790', 297692378
    

    然后我添加了一个名为RANK存储最终结果的新列。

    ALTER TABLE TEST ADD [RANK] int;
    
    GO
    

    我使用 LAG() 窗口函数来计算当前行和下一行之间的 DATEDIFF。

    SELECT DTTM, SESSION_ID,
           DATEDIFF(minute, COALESCE(LAG(DTTM) OVER (ORDER BY DTTM, SESSION_ID), DTTM), DTTM) DIF_MIN
    FROM   TEST
    GO
    
    DTTM | 会话ID | DIF_MIN
    :-------------------- | ----------: | ------:
    29/08/2016 14:24:28 | 297692378 | 0
    2017 年 4 月 13 日 23:54:53 | 297692378 | 327450
    2017 年 4 月 13 日 23:59:53 | 297692378 | 5个
    14/04/2017 00:04:52 | 297692378 | 5个
    14/04/2017 00:04:53 | 297692378 | 0
    2017 年 4 月 14 日 00:44:53 | 297692378 | 40
    

    然后我使用了一个 CURSOR 来计算 RANK 字段。基本上它会在记录之间累积分钟数,直到达到 20 分钟或更长时间。

    DECLARE @dttm datetime,
            @session_id int,
            @diff_min int,
            @acm_diff int,
            @rank int,
            @last_dttm datetime;
    
    SET @diff_min = 0;
    SET @acm_diff = 0;
    SET @rank = 0;
    SET @last_dttm = NULL;
    
    DECLARE curMin CURSOR FAST_FORWARD  FOR
    SELECT DTTM, SESSION_ID,
           DATEDIFF(minute, COALESCE(LAG(DTTM) OVER (ORDER BY DTTM, SESSION_ID), DTTM), DTTM) DIF_MIN
    FROM   TEST
    
    OPEN curMin;
    FETCH NEXT FROM curMin INTO @dttm, @session_id, @diff_min;
    
    WHILE @@FETCH_STATUS = 0  
    BEGIN
        IF @last_dttm IS NULL OR @acm_diff + @diff_min > 20
        BEGIN
            SET @rank = @rank + 1;
            SET @acm_diff = 0;
        END
        ELSE
        BEGIN
            SET @acm_diff = @acm_diff + @diff_min;
        END
        
        UPDATE TEST
        SET    [RANK] = @rank
        WHERE  DTTM = @dttm
        AND    SESSION_ID = @session_id;
        
        SET @last_dttm = @dttm;
        
        FETCH NEXT FROM curMin INTO @dttm, @session_id, @diff_min;
    END
    
    CLOSE curMin;
    
    SELECT   DTTM, SESSION_ID,
             DATEDIFF(minute, DTTM, COALESCE(LEAD(DTTM) OVER (ORDER BY DTTM, SESSION_ID), DTTM)) DIF_MIN,
             [RANK]
    FROM     TEST 
    ORDER BY DTTM, SESSION_ID;
    GO
    
    DTTM | 会话ID | DIF_MIN | 秩
    :-------------------- | ----------: | ------: | ---:
    29/08/2016 14:24:28 | 297692378 | 327450 | 1个
    2017 年 4 月 13 日 23:54:53 | 297692378 | 5 | 2个
    2017 年 4 月 13 日 23:59:53 | 297692378 | 5 | 2个
    14/04/2017 00:04:52 | 297692378 | 0 | 2个
    14/04/2017 00:04:53 | 297692378 | 40 | 2个
    2017 年 4 月 14 日 00:44:53 | 297692378 | 0 | 3个
    

    dbfiddle在这里

    • 2

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve