根据条件SQL创建新变量

问题描述 投票:0回答:1

我正在开发一个项目,并有一个包含以下数据的表格: 日期时间用户名类型session_time 2023-08-28 07:56:50.0000000 aavery35 登录 NULL 2023-08-28 08:07:53.0000000 aavery35 视图 NULL 2023-08-28 08:08:48.0000000 aavery35 更新 NULL 2023-08-28 08:08:48.0000000 aavery35 更新 NULL 2023-08-28 08:08:48.0000000 aavery35 更新 NULL

我正在尝试找到一种方法来更新 session_time 变量以查找 date = date 和 username = username 然后减去注销:时间 - 登录:时间

问题的一部分是每个用户不一定都有注销时间。在这种情况下,我想转到他们当天的最后一个操作,并为该日期、时间和用户名创建一个新行,并创建一个注销实例。

我认为所有“类型”变量都位于同一列中是不可能的。因此,我创建了三个新变量 login_time、logout_time、session_time。然后我运行了以下代码:

更改表##remote_users 添加session_time日期;

更改表##remote_users 添加login_time时间;

更改表##remote_users 添加logout_time时间;

更新##remote_users 设置登录时间=时间 其中用户名 = 用户名 AND 日期 = 日期 AND Type = '登录';

更新##remote_users 设置注销时间 = 时间 其中用户名 = 用户名 AND 日期 = 日期 AND Type = '注销';

更新##remote_users 设置会话时间 = 登录时间 - 注销时间 其中用户名 = 用户名 AND 日期 = 日期;

选择日期、时间、用户名、类型、登录时间、注销时间 来自##remote_users WHERE 类型 = '登录' 或 类型 = '注销' 或 类型 = '会话超时' 按用户名下单

这很接近,因为它创建了我需要的变量,但 session_time 更新不起作用,它给出了以下错误:Msg 8117,Level 16,State 1,Line 57 操作数数据类型时间对于减法运算符无效。

此外,没有注销时间的用户会获得变量 logout_time 的空值。

谢谢您的帮助!

sql sql-server sql-update variable-assignment datediff
1个回答
0
投票

您似乎正在尝试根据表中的

session_time
login_time
列更新
logout_time
列,并且您面临数据类型和处理用户没有注销的情况的问题时间。以下是解决此问题的方法:

  1. 数据类型问题: 您遇到的错误“操作数数据类型时间对于减法运算符无效”是因为您尝试减去两个

    time
    数据类型。要计算会话时间,您需要使用
    datetime
    timestamp
    数据类型。您不能像使用数字那样直接减去
    time
    值。

  2. 处理丢失的注销时间: 您提到有些用户可能没有注销时间。在这种情况下,您需要单独处理这种情况。一种方法是假设如果没有明确的注销时间,会话将持续到一天结束(午夜)。

这里有一个修改后的 SQL 脚本可以帮助您实现此目的:

-- Step 1: Add session_time as a datetime column
ALTER TABLE ##remote_users ADD session_time DATETIME;

-- Step 2: Calculate session_time for logins and handle missing logouts
UPDATE ##remote_users
SET session_time = 
    CASE
        WHEN Type = 'login' THEN
            CASE
                WHEN (LEAD(Type) OVER (PARTITION BY username, date ORDER BY time) = 'logout') THEN
                    DATEDIFF(SECOND, time, LEAD(time) OVER (PARTITION BY username, date ORDER BY time))
                ELSE
                    DATEDIFF(SECOND, time, DATEADD(DAY, 1, CAST(date AS DATETIME)))
            END
        ELSE NULL
    END
WHERE Type = 'login' OR Type = 'logout';

-- Step 3: Display the results
SELECT date, time, username, type, session_time
FROM ##remote_users
WHERE type = 'login' OR type = 'logout'
ORDER BY username, date, time;

以下是该脚本功能的详细说明:

  • 第 1 步:添加
    session_time
    列作为
    DATETIME
    来存储会话持续时间。
  • 第 2 步:更新登录条目的
    session_time
    列。如果找到相同用户和日期的注销条目,则会计算会话持续时间(以秒为单位)。如果没有注销条目,则假定会话持续到午夜。
  • 第 3 步:显示登录和注销条目的结果以及会话时间。

请确保根据需要调整脚本以适应您的特定数据库系统,因为不同数据库系统之间的 SQL 语法可能略有不同。

© www.soinside.com 2019 - 2024. All rights reserved.