如何根据列过滤器缩小不同的行?

时间:2012-04-30 11:15:20

标签: sql sql-server sql-server-2008 greatest-n-per-group

我正在尝试搜索最近发生的一堆事务,但只希望每次事务都返回一次。我对代码问题的尝试更好地解释了它。

SELECT 
DISTINCT    TransactionCode
    ,       IdKey 
FROM        TransTable 
WHERE       TransactionCode IN (<massive list of ids...>) 
AND         ActionDate      < GETDATE() 
ORDER BY    ActionDate DESC

我想要每个事务代码的一个实例,按日期排序(也就是最近发生的那个事务),并且还返回了idKey。想法?

3 个答案:

答案 0 :(得分:5)

SELECT TransactionCode, 
       IdKey
FROM
  (
    SELECT TransactionCode, 
           IdKey,
           ROW_NUMBER() OVER(PARTITION BY TransactionCode 
                             ORDER BY ActionDate DESC) AS rn
    FROM TransTable 
    WHERE TransactionCode in (1,2,3) AND 
          ActionDate < GETDATE() 
  ) T
WHERE rn = 1

答案 1 :(得分:2)

您需要通过在TransactionCode列上对它们进行分区,然后按ActionDate按降序对它们进行排序,从而为行中的每一行分配行号。这部分。根据此逻辑分配行号后,您只能从派生表输出中过滤掉rownum 1 的行。这将获取所有交易代码。您可以根据需要在以下查询中添加过滤条件。

Click here to view the demo in SQL Fiddle

脚本

CREATE TABLE dbo.TransTable
(
        IdKey           INT         NOT NULL IDENTITY
    ,   TransactionCode VARCHAR(10) NOT NULL
    ,   ActionDate      DATETIME    NOT NULL
);

INSERT INTO dbo.TransTable (TransactionCode, ActionDate) VALUES
    ('code 1', '2012-04-27 01:04:12.467'),
    ('code 1', '2012-04-22 09:16:29.354'),
    ('code 2', '2012-04-12 11:04:27.751'),
    ('code 1', '2012-06-19 12:27:12.232'),
    ('code 2', '2012-04-04 05:22:17.467'),
    ('code 3', '2012-05-01 08:49:12.951'),
    ('code 3', '2012-05-13 06:12:12.234');

SELECT  IdKey
    ,   TransactionCode
    ,   ActionDate
FROM
(
    SELECT  IdKey
        ,   TransactionCode
        ,   ActionDate
        ,   ROW_NUMBER() OVER (
                        PARTITION  BY TransactionCode 
                        ORDER BY ActionDate DESC
            ) rownum
    FROM    dbo.TransTable
    WHERE   ActionDate < GETDATE()
) t1 WHERE rownum = 1;

输出

IdKey TransactionCode ActionDate
----- --------------- -----------------------
1     code 1          2012-04-27 01:04:12.467
3     code 2          2012-04-12 11:04:27.750

答案 2 :(得分:1)

可能是,你可以这样找到:

;WITH Cte AS (
SELECT 
    ROW_Number() over (partition by TransactionCode, IdKey  ORDER BY ActionDate DESC) RowID,
    TransactionCode, IdKey      
FROM TransTable 
WHERE TransactionCode in (Massive list of IDs) 
AND ActionDate < GETDATE() 
)
SELECT * FROM Cte WHERE RowID = 1