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

Posted

技术标签:

【中文标题】如何根据列过滤器缩小不同的行?【英文标题】:How do I narrow down the distinct rows based on column filters? 【发布时间】:2012-05-10 02:22:05 【问题描述】:

我正在尝试搜索最近发生的一堆交易,但只希望每笔交易返回一次。我对代码问题的尝试比我能解释得更好。

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

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

【问题讨论】:

对表应用了唯一性不是吗?我无法更改表格。 【参考方案1】:
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

【讨论】:

我认为子选择也应该返回ActionDate,因为 OP 似乎想要对结果集进行排序。 @AndriyM 可能是这样。我将order by 子句解释为试图仅获取每个TransactionCode 的“最后”行而不是结果集的排序顺序。 想就是这样,非常感谢。对分区不是特别熟悉,现在一定要仔细看看! “order by”是我尝试获取最后/最新行的尝试。 @user1365650 - Here is the documentation for row_number() over()【参考方案2】:

您需要通过在TransactionCode 列上对它们进行分区来为表中的每一行分配行号,然后按降序对它们进行排序ActionDate,以便您在该部分的顶部获得最新的事务。一旦基于此逻辑分配了行号,您就可以从派生表输出中仅过滤出具有 1rownum 值的行。这将获取所有交易代码。您可以根据需要在下面的查询中添加过滤条件。

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

【讨论】:

【参考方案3】:

可能,你可以这样找到:

;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

【讨论】:

以上是关于如何根据列过滤器缩小不同的行?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据外部向量过滤表的行?

PySpark - 如何根据列中的两个值从数据框中过滤出连续的行块

Python - 根据列条件比较 .csv 文件的行

Python Datatable/Pydatatable:如何通过正则表达式过滤数据表中的行并根据过滤器为新变量赋值

根据列中的条件对数据框中的行进行子集/过滤

scala 根据具有相同值的 2 列过滤掉连接 df 中的行 - 最佳方式