【问题标题】:partition by values from another related row按来自另一个相关行的值进行分区
【发布时间】:2015-09-21 13:12:20
【问题描述】:

我试图在表中为每个帐户识别最新的合并交易。该表填充了帐户合并,最新的合并交易是较大的 merge_tx_id

源表:

| merge_tx_id | merge_from_id | merge_to_id |
|-------------|---------------|-------------|
|           1 |           546 |         100 |
|           2 |           789 |         802 |
|           3 |           123 |         456 |
|          33 |           456 |         123 |
|         222 |           802 |         789 |
|         333 |           123 |         456 |

merge_tx_id IN (3,33,333) 是基于出现在另一行中的 merge_from_id 或 merge_to_id 的同一帐户,在此示例中,执行了合并,然后稍后再次“取消合并”。最新的 id 应该是 '456'

| merge_tx_id | merge_from_id | merge_to_id |
|-------------|---------------|-------------|
|           3 |           123 |         456 |
|          33 |           456 |         123 |
|         333 |           123 |         456 |

merge_tx_id IN (2,222) 是基于另一行出现的merge_from_id或merge_to_id的同一个账户,最新的是'789'

| merge_tx_id | merge_from_id | merge_to_id |
|-------------|---------------|-------------|
|           2 |           789 |         802 |
|         222 |           802 |         789 |

merge_tx_id IN (1) 与任何其他行都不相关,最新的 id 是 '100'

| merge_tx_id | merge_from_id | merge_to_id |
|-------------|---------------|-------------|
|           1 |           546 |         100 |

我认为我需要将表连接到自身并执行 RANK,但我不清楚如果可以的话,如何在(第 1 列或第 2 列)上执行分区。

想要的结果是

| merge_tx_id | merge_from_id | merge_to_id |
|-------------|---------------|-------------|
|           1 |           546 |         100 |
|         333 |           123 |         456 |
|         222 |           802 |         789 |

示例:http://sqlfiddle.com/#!3/9a94b6/11

【问题讨论】:

    标签: sql-server tsql partitioning rank


    【解决方案1】:

    您可以使用以下查询:

    SELECT merge_tx_id, merge_from_id, merge_to_id
    FROM (
    SELECT merge_tx_id, merge_from_id, merge_to_id,
           ROW_NUMBER() OVER (PARTITION BY x.merge1, y.merge2
                              ORDER BY merge_tx_id DESC) AS rn
    FROM merge_grp
    CROSS APPLY (SELECT CASE WHEN merge_from_id < merge_to_id 
                                THEN merge_from_id
                                ELSE merge_to_id
                        END AS merge1) AS x
    CROSS APPLY (SELECT CASE WHEN merge_from_id >= merge_to_id 
                                THEN merge_from_id
                                ELSE merge_to_id
                             END AS merge2) AS y  ) t
    WHERE t.rn = 1                     
    

    该查询使用两个CROSS APPLY 子句,以便将merge_from_idmerge_to_id 重新排列为两个等效列merge1merge2,它们按升序排列。 ROW_NUMBER 使用这两个计算列对行进行分区,因此可以根据merge1merge2 选择具有最大merge_tx_id 的行。

    Demo here

    【讨论】:

    • @bosco_taco 很高兴为您提供帮助,欢迎来到 Stack Overflow。如果此答案或任何其他答案解决了您的问题,请将其标记为已接受。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-10
    • 2018-07-19
    • 2014-07-22
    • 2021-07-31
    • 1970-01-01
    • 2011-02-26
    相关资源
    最近更新 更多