Sql server TSQL以获得排序的不同记录,然后应用行号

Sql server TSQL以获得排序的不同记录,然后应用行号,sql-server,tsql,sql-server-2008,Sql Server,Tsql,Sql Server 2008,我问了一个关于在软件激活场景中处理锁定的问题,在这个场景中,当处理新的激活时,旧的激活被锁定 我遇到了一个问题,希望有人能帮助我。假设Activations表有以下列: CustomerName、ProductName、KeyCode、ActivationDate DECLARE @tbl TABLE ( CustomerName VARCHAR(20), ProductName VARCHAR(20), KeyCode INT,

我问了一个关于在软件激活场景中处理锁定的问题,在这个场景中,当处理新的激活时,旧的激活被锁定

我遇到了一个问题,希望有人能帮助我。假设Activations表有以下列:

CustomerName、ProductName、KeyCode、ActivationDate

DECLARE @tbl TABLE
(
    CustomerName    VARCHAR(20),
    ProductName     VARCHAR(20),
    KeyCode         INT,
    ActivationDate  DATETIME
)


INSERT INTO @tbl
SELECT 'cmp1', 'game', 28734, GETDATE() -1    UNION ALL
SELECT 'cmp1', 'game', 28734, GETDATE() -1.5  UNION ALL
SELECT 'cmp1', 'game', 28734, GETDATE() -1.2  UNION ALL
SELECT 'cmp1', 'game', 28734, GETDATE() -1.8  UNION ALL
SELECT 'cmp1', 'game', 28734, GETDATE()       UNION ALL
SELECT 'cmp1', 'game', 28734, GETDATE() -17   UNION ALL
SELECT 'cmp2', 'game', 28736, GETDATE() -1    UNION ALL
SELECT 'cmp2', 'game', 28736, GETDATE() -1.5  UNION ALL
SELECT 'cmp2', 'game', 28736, GETDATE() -1.2  UNION ALL
SELECT 'cmp2', 'game', 28736, GETDATE() -1.8  UNION ALL
SELECT 'cmp2', 'game', 28736, GETDATE()       UNION ALL
SELECT 'cmp2', 'game', 28736, GETDATE() -17     


SELECT        ROW_NUMBER() OVER(ORDER BY ActivationDate DESC) RowNumber,
              CustomerName, 
              ProductName, 
              KeyCode, 
              ActivationDate        
FROM @tbl workTable
WHERE ActivationDate != 
    (
        SELECT MAX(ActivationDate)
        FROM @tbl checkTable
        WHERE workTable.CustomerName = checkTable.CustomerName
            AND workTable.ProductName = checkTable.ProductName
            AND workTable.KeyCode = checkTable.KeyCode
    )
我需要获得唯一的CustomerName、ProductName和KeyCode数据,因为您可以多次激活同一台机器。结果集需要由ActivationDate DESC排序,以便我可以按激活的顺序处理数据。因此,在我的场景中,我可能会允许最后两个激活工作,所有这些都是在登录到锁定表之前进行的,因此它们会被锁定,并记录新的激活

如何获得唯一/不同的结果集,然后应用行号,以便迭代结果集并放弃最新的激活,并使用较旧的激活将其锁定


谢谢。

我想这可以满足您的要求:

select t.CustomerName, t.ProductName, t.KeyCode, t.MaxDate,
       row_number() over (order by t.MaxDate desc) as RowNum
    from (select CustomerName, ProductName, KeyCode, max(ActivationDate) as MaxDate
              from Activations
              group by CustomerName, ProductName, KeyCode) t
也可以使用一个

;with cteMaxDate as (
    select CustomerName, ProductName, KeyCode, max(ActivationDate) as MaxDate
        from Activations
        group by CustomerName, ProductName, KeyCode
)
select t.CustomerName, t.ProductName, t.KeyCode, t.MaxDate,
       row_number() over (order by t.MaxDate desc) as RowNum
    from cteMaxDate t

我想这就是你想要的: 您需要所有行号不是最大激活日期的行

DECLARE @tbl TABLE
(
    CustomerName    VARCHAR(20),
    ProductName     VARCHAR(20),
    KeyCode         INT,
    ActivationDate  DATETIME
)


INSERT INTO @tbl
SELECT 'cmp1', 'game', 28734, GETDATE() -1    UNION ALL
SELECT 'cmp1', 'game', 28734, GETDATE() -1.5  UNION ALL
SELECT 'cmp1', 'game', 28734, GETDATE() -1.2  UNION ALL
SELECT 'cmp1', 'game', 28734, GETDATE() -1.8  UNION ALL
SELECT 'cmp1', 'game', 28734, GETDATE()       UNION ALL
SELECT 'cmp1', 'game', 28734, GETDATE() -17   UNION ALL
SELECT 'cmp2', 'game', 28736, GETDATE() -1    UNION ALL
SELECT 'cmp2', 'game', 28736, GETDATE() -1.5  UNION ALL
SELECT 'cmp2', 'game', 28736, GETDATE() -1.2  UNION ALL
SELECT 'cmp2', 'game', 28736, GETDATE() -1.8  UNION ALL
SELECT 'cmp2', 'game', 28736, GETDATE()       UNION ALL
SELECT 'cmp2', 'game', 28736, GETDATE() -17     


SELECT        ROW_NUMBER() OVER(ORDER BY ActivationDate DESC) RowNumber,
              CustomerName, 
              ProductName, 
              KeyCode, 
              ActivationDate        
FROM @tbl workTable
WHERE ActivationDate != 
    (
        SELECT MAX(ActivationDate)
        FROM @tbl checkTable
        WHERE workTable.CustomerName = checkTable.CustomerName
            AND workTable.ProductName = checkTable.ProductName
            AND workTable.KeyCode = checkTable.KeyCode
    )


如果你想要不止一个

SELECT  ROW_NUMBER() OVER(ORDER BY ActivationDate DESC) RowNumber,
        CustomerName, 
        ProductName, 
        KeyCode, 
        ActivationDate      
FROM @tbl workTable
WHERE NOT ActivationDate IN 
    (
        SELECT TOP 2 ActivationDate
        FROM @tbl checkTable
        WHERE workTable.CustomerName = checkTable.CustomerName
            AND workTable.ProductName = checkTable.ProductName
            AND workTable.KeyCode = checkTable.KeyCode
        ORDER BY ActivationDate DESC
    )

它不会触及这两个:cmp2,游戏,28736,'2/25/11 8:50'和cmp1,游戏,28734,'2/25/11 8:50'