查询重复行,然后通过另一个查询运行最旧的重复ID

时间:2015-11-17 20:06:49

标签: sql sql-server sql-server-2008 tsql

好吧,所以这个有点令人困惑,我不太确定如何使用TSQL或者甚至可以使用TSQL。

我有一个使用Microsoft SQL Server 2008的软件。有一个名为“iLicuserinfo”的表,其中包含已登录用户的列表,用于为该人员分配并发用户许可证。该表的一个例子如下......

根据要求,样本数据为文本而非图像......

WSID    LoginName   SessionID   Last_Login
WK-221  asmith      370         2015-11-17 13:51:32.543
WK-221  asmith      380         2015-11-17 14:30:05.473
WK-220  jcavan      70          2015-11-17 07:20:21.573
WK-230  ccarmore    450         2015-11-17 08:14:42.747
WK-247  jspoon      160         2015-11-17 11:22:07.060
WK-238  mcalhone    10          2015-11-17 14:24:05.133
WK-250  bcasey      270         2015-11-17 10:48:51.230
WK-203  camel       260         2015-11-17 13:19:36.613
WK-205  kwilson     130         2015-11-17 13:32:52.010

会发生的情况是,最多允许有25个并发用户,并且会强制执行。该软件很糟糕(并且供应商拒绝纠正它),并且经常会崩溃并且不会清除iLicuserinfo列表中的许可证。

更正此问题的过程是查询该表,查找具有匹配的WSID的任何行(这是许可证所绑定的工作站的主机名),找到两个或更多个副本中哪个是最旧的,取该行的SessionID,然后运行以下查询将其清除....

EXEC dbo.CleanAppSessions
WAITFOR DELAY '00:00:03'
EXEC dbo.login_proc
WAITFOR DELAY '00:00:03'
EXEC dbo.sysCleanAppSessions
WAITFOR DELAY '00:00:03'
EXEC dbo.sysReleaseAppSession  @pAppSessionId = NULL

其中“NULL”替换为发现的副本的会话ID。

我想要做的是创建一个拉取许可证表的查询,按WSID排序,找到重复项,然后重复这些查询获取SessionID,然后使用该会话ID代替“NULL”运行上面的查询。 / p>

使用上面链接中显示的表数据的屏幕截图,会手动清除SessionID为370的行,因为上一次登录是在SessionID 380之前一小时。

到目前为止,我找不到一种方法来形成一个查询,其中包含比较行所需的逻辑,并标记哪些是可以清除的实际挂起的许可证,然后通过上面的脚本运行一个或多个SessionID一次一个。

这看起来对我来说是一项非常重要的工作,但也许有一个SQL quru可以指出我正确的方向实现我想做的事情?

2 个答案:

答案 0 :(得分:0)

要查找欺骗并获取最早的时间戳,请使用汇总查询。

SELECT SessionID
FROM Table INNER JOIN (
    SELECT WSID, 
        MIN(timestampField) AS timestampField
    FROM Table
    GROUP BY WSID
    HAVING COUNT(*) > 1
) t ON Table.WSID = t.WSID AND 
    Table.timestampField = t.timestampField

要将其循环通过其余代码,请使用cursor

答案 1 :(得分:0)

使用ROW()函数,你可以得到重复的记录(注意我抓住那些> 1)然后循环调用你的函数。我假设您只需要运行其他SP一次,这样它们就不在循环中了。

DECLARE @Table as table(WSID varchar(50),LoginName varchar(50),SessionID int,Last_Login datetime)
INSERT INTO @Table values ('WK-221','asmith',370,'2015-11-17 13:51:32')
INSERT INTO @Table values ('WK-221','asmith',380,'2015-11-17 14:30:05')
INSERT INTO @Table values ('WK-220','jcavan',70,'2015-11-17 07:20:21')
INSERT INTO @Table values ('WK-230','ccarmore',450,'2015-11-17 08:14:42')

DECLARE @SessionId int

EXEC dbo.CleanAppSessions
WAITFOR DELAY '00:00:03'
EXEC dbo.login_proc
WAITFOR DELAY '00:00:03'
EXEC dbo.sysCleanAppSessions
WAITFOR DELAY '00:00:03'

DECLARE crsr_Tmp CURSOR SCROLL FOR 
    SELECT SessionID FROM (
        SELECT *,ROW_NUMBER() OVER(PARTITION BY WSID ORDER BY Last_Login desc) Row FROM @Table
    ) Tmp
    where Row > 1

OPEN crsr_Tmp;
--Start FETCH process      
FETCH NEXT FROM crsr_Tmp
    INTO @SessionId
WHILE @@FETCH_STATUS = 0
BEGIN
    EXEC dbo.sysReleaseAppSession  @pAppSessionId = @SessionId

    --Grab next record from cursor
    FETCH NEXT FROM crsr_Tmp
        INTO @SessionId
END
DEALLOCATE crsr_Tmp --clean up cursor