【问题标题】:Select an information from a row based on the maximum value of specific column in a group by?根据分组中特定列的最大值从一行中选择一条信息?
【发布时间】:2017-12-06 22:17:45
【问题描述】:

我有这个数据


----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Id| Date_Opera | Emitter    |   EmitterIBAN                         |  Receiver    |   ReceiverIBAN                           |         Adresss                          |     Value 
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1, | 2017-07-07 | Ernst,         HR53 8827 2118 4692 8207 5,           Kimbra,         CH20 1042 6T0N MDTG JT47 U,                     3256 Arrowood Point         0002,        121.72
2, | 2017-09-27 | Keene,         SK81 1004 7484 7505 6308 9259,        Torrance,       RO23 ZWTR OJKK VAU9 T5P4 2GDY,                  35197 Green Ridge Way,                   82.52
3, | 2017-10-17 | Ernst,         HR53 8827 2118 4692 8207 5,           Kimbra,         CH20 1042 6T0N MDTG JT47 U,                     3256 Arrowood Point         0048,        51.81
4, | 2017-05-01 | Korie,         ME43 9833 9830 7367 4239 60,Roy,      IL69            9686 1536 8102 2219 165,                        5 Swallow Alley,                         88.01
5, | 2017-11-17 | Ernst,         HR53 8827 2118 4692 8207 5,           Kimbra,         CH20 1042 6T0N MDTG JT47 U,                     3256 Arrowood Point         0001,        133.99
6, | 2017-10-10 | Charmine,      BG92 TOXX 8380 785I JKRQ JS,          Sarette,        MU67 RYRU 9293 5875 6859 7111 075X HR,          8 Sage Place,                            36.30
7, | 2017-07-18 | Ernst,         HR53 8827 2118 4692 8207 5,           Kimbra,         CH20 1042 6T0N MDTG JT47 U,                     3256 Arrowood Point         0004,        186.99

我想在下面得到这样的结果

  • 计算一对 EmitterIBAN 和 ReceiverIBAN 进行的操作数
  • 计算每对 EmitterIBAN 和 ReceiverIBAN 的总和值
  • 并通过取最大地址值按可以不同的地址分组

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
sum| Date_Opera | Emitter    |   EmitterIBAN                         |  Receiver    |   ReceiverIBAN                           |         Adresss                          |     SumValue 
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4, | 2017-11-17 |  Ernst,         HR53 8827 2118 4692 8207 5,           Kimbra,         CH20 1042 6T0N MDTG JT47 U,                     3256 Arrowood Point           0048,      494,51
1, | 2017-09-27 |  Keene,         SK81 1004 7484 7505 6308 9259,        Torrance,       RO23 ZWTR OJKK VAU9 T5P4 2GDY,                  35197 Green Ridge Way,                   82.52
1, | 2017-05-01 |  Korie,         ME43 9833 9830 7367 4239 60,Roy,      IL69            9686 1536 8102 2219 165,                        5 Swallow Alley,                         88.01
1, | 2017-10-10 |  Charmine,      BG92 TOXX 8380 785I JKRQ JS,          Sarette,        MU67 RYRU 9293 5875 6859 7111 075X HR,          8 Sage Place,                            36.30

所以为了得到这个结果,我使用了这个请求

Select  count(1) as NumberOperation, 
        MAX(Emitter) as EmitterName, 
        EmitterIban, 
        MAX(Receiver) as ReceiverName, 
        ReceiverIban,
        MAX(ReceiverAddress) as ReceiverAddress,
        SUM([Value]) as SumValues
FROM TableEsperadoceTransaction
Group By EmitterIban,
         ReceiverIban

但是现在,我想要的是,而不是像之前的示例那样获取最大地址,我想从具有最大数据时间操作的记录中获取地址。 这是我的数据结果的示例


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
sum| Date_Opera | Emitter    |   EmitterIBAN                         |  Receiver    |   ReceiverIBAN                           |         Adresss                          |     SumValue 
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4, | 2017-11-17 |  Ernst,         HR53 8827 2118 4692 8207 5,           Kimbra,         CH20 1042 6T0N MDTG JT47 U,                     3256 Arrowood Point           0002,      494,51
1, | 2017-09-27 |  Keene,         SK81 1004 7484 7505 6308 9259,        Torrance,       RO23 ZWTR OJKK VAU9 T5P4 2GDY,                  35197 Green Ridge Way,                   82.52
1, | 2017-05-01 |  Korie,         ME43 9833 9830 7367 4239 60,Roy,      IL69            9686 1536 8102 2219 165,                        5 Swallow Alley,                         88.01
1, | 2017-10-10 |  Charmine,      BG92 TOXX 8380 785I JKRQ JS,          Sarette,        MU67 RYRU 9293 5875 6859 7111 075X HR,          8 Sage Place,                            36.30

所以我的问题是我该如何提出这样的要求?

PS:我有 2.4 亿条记录

编辑: 我有 3 个索引

  1. 日期操作
  2. EmitterIban
  3. ReceiverIban

【问题讨论】:

  • 这张表有索引吗?
  • 是的@JohnHC 我在 EmitterIBAN 和 ReceiverIBAN 中有两个索引

标签: sql sql-server tsql sql-server-2005


【解决方案1】:

你可以试试这样的:

Select  count(1) as NumberOperation, 
        MAX(t.Emitter) as EmitterName, 
        t.EmitterIban, 
        MAX(t.Receiver) as ReceiverName, 
        t.ReceiverIban,
        (SELECT TOP 1 x.RecieverAddress 
         FROM TableEsperadoceTransaction AS x 
         WHERE x.EmitterIban=t.EmitterIban AND x.RecieverIban=t.RecieverIban
         ORDER BY Data_Opera DESC) as ReceiverAddress,
        SUM(t.[Value]) as SumValues
FROM TableEsperadoceTransaction AS t
Group By t.EmitterIban,
         t.ReceiverIban;

我将您的MAX(Address) 替换为获取最高地址的子选择,按Data_Opera 排序,条件相同...

顺便说一句:在日期列上放置索引会有所帮助...

更新:这可能会更快...

Select  count(1) as NumberOperation, 
        MAX(t.Emitter) as EmitterName, 
        t.EmitterIban, 
        MAX(t.Receiver) as ReceiverName, 
        t.ReceiverIban,
        (SELECT TOP 1 x.RecieverAddress 
         FROM TableEsperadoceTransaction AS x 
         WHERE x.EmitterIban=t.EmitterIban 
           AND x.RecieverIban=t.RecieverIban
           AND x.Data_Opera=MAX(t.Data_Opera)) as ReceiverAddress,
        SUM(t.[Value]) as SumValues
FROM TableEsperadoceTransaction AS t
Group By t.EmitterIban,
         t.ReceiverIban;

GROUP BY 将允许您直接获取MAX(t.Data_Opera)。使用 三列索引,您应该可以非常快速地获得地址值。

【讨论】:

  • 有了子查询,这不是要命中每一行的索引吗?
  • 我认为引擎将足够聪明,可以内联...您使用ROW_NUMBER() 的方法可能会产生一些开销,因为您必须选择每一行,对它们进行编号并抛出大部分他们又走了。拥有一个包含所有三列和Data_Opera DESC 的索引可能会有所帮助。因此引擎可以在任何情况下选择第一个拟合值......
  • @Shnugo 我有 3 个索引 Date_Operation、EmitterIban、ReceiverIban 我应该用 3 列创建索引吗?
  • 检查一下,引擎非常智能,结构如此简单(很多,但很简单)。按照上面的建议添加 多列索引 可能会有所帮助...
  • @Shnugo 我今天早上开始执行请求,我正在等待结果。在我的用例中,我必须从具有相同结构的 4 个表中选择和插入,所以从执行开始到现在已经过去了 6 个小时,这就是为什么它花了很多时间。我想我明天会尝试新版本。我没有什么问题,我对 4 列进行分组,为这 4 列创建索引会更有趣吗?
【解决方案2】:

我认为你应该使用窗口函数(SQL 2012+):

Select  count(1) as NumberOperation, 
        MAX(t.Emitter) as EmitterName, 
        t.EmitterIban, 
        MAX(t.Receiver) as ReceiverName, 
        t.ReceiverIban,
        FIRST_VALUE(x.RecieverAddress) OVER (PARTITION BY t.EmitterIban, t.ReceiverIban ORDER BY Data_Opera DESC),
        SUM(t.[Value]) as SumValues
FROM TableEsperadoceTransaction AS t
Group By t.EmitterIban,
         t.ReceiverIban;

【讨论】:

  • 很好的解决方案 (+1),但值得一提的是,这个 FIRST_VALUE() OVER(...) 在 v2012 之前不可用。
【解决方案3】:

我在 CTE 中使用了 row_number(),自加入聚合:

with CTE as
(
select t1.*, row_number() over(partition by EmitterIban, ReceiverIban order by Date_Opera desc)  as rn
from TableEsperadoceTransaction t1
)

select a1.EmitterIban,a1.emitter as EName, 
       a1.ReceiverIban, a1.receiver as RName,
       a1.ReceiverAddress
       max(a2.rn) as NumberOperation,
       sum(a2.value) as SumValues
from CTE a1
inner join CTE a2
on a1.EmitterIban = a2.EmitterIban
and a1.ReceiverIban = a2.ReceiverIban
where a1.rn = 1
group by a1.EmitterIban,a1.emitter, 
         a1.ReceiverIban, a1.receiver,
         a1.ReceiverAddress

【讨论】:

    猜你喜欢
    • 2016-11-26
    • 2022-08-23
    • 2011-06-17
    • 1970-01-01
    • 2012-05-29
    • 2021-09-12
    • 2016-08-19
    • 1970-01-01
    • 2021-12-21
    相关资源
    最近更新 更多