如何获得两列组合的最后记录?

问题描述 投票:2回答:2

我认为这种情况可以与CamelCamelCamel,Keepa等服务相提并论。可以说,我跟踪了两个国家/地区每天的商品价格。所以我的桌子,叫它Trend,看起来像这样

Id     Created      ArticleId    Country    Price
-------------------------------------------------
01     19/11/05     452          US         45.90
02     19/11/05     452          CA         52.99
03     19/11/05     452          MX         99.99
04     19/11/06     452          US         20.00
05     19/11/06     452          CA         25.00
06     19/11/06     452          MX         50.00
...                
97     19/11/05     738          US         12.99
98     19/11/05     738          CA         17.50
99     19/11/05     738          MX         45.50

所以是第二天,我想更新Trend表。如果某个国家/地区的价格仍然相同,则跳过商品/国家/地区组合。如果有新价格,我会添加一个新记录。

现在我要查询表以获取每个ArticleId / Country组合。但只有它的最后一条记录(按时间戳排序)。因此,以上述示例为例,我希望获得04 05的记录06ArticleId452。不是010203

所以我从这个基本查询开始。但是,如何更改它以达到预期效果?

SELECT
    *
FROM
    Trend
ORDER BY 
    Created DESC
sql sql-server tsql greatest-n-per-group
2个回答
1
投票

一种方法使用相关子查询进行过滤:

select t.*
from trend t
where t.created = (
    select max(t1.created) 
    from trend t1
    where t1.articleId = t.articleId and t1.country = t.country
)

为了提高性能,您需要在(articleId, country, created)上建立索引。

您可能还想考虑使用反left join方法:

select t.*
from trend t
left join trend t1 
    on  t1.articleId = t.articleId 
    and t1.country = t.country
    and t1.created > t.created
where t1.articleId is null

最后,另一种典型的解决方案是使用汇总查询将表连接起来:

select t.*
from trend t
inner join (
    select articleId, country, max(created) created
    from trend
    group by articleId, country
) t1 
    on  t1.articleId = t.articleId 
    and t1.country = t.country
    and t1.created = t.created

哪种解决方案效果更好,取决于数据的大小和分布。


1
投票

您可以结合使用DISTINCTCROSS APPLY

SELECT DISTINCT ca.Id, ca.Created, t.ArticleId, t.Country, ca.Price
FROM Trend t
CROSS APPLY (SELECT TOP 1 Id, Created, Price
             FROM Trend
             WHERE ArticleId = t.ArticleId AND Country = t.Country
             ORDER BY Created DESC) ca

如果您在性能方面遇到问题,则可能需要创建一个索引。

CREATE NONCLUSTERED INDEX [NC_Trend_ArticleId] ON [Trend]
(
    [ArticleId] ASC,
    [Country] ASC,
    [Created] ASC
)
INCLUDE ([Price])

[大概IdPRIMARY KEY,并且已经被CLUSTERED INDEX覆盖,如果是这样,则以上内容在大多数情况下都适用。

© www.soinside.com 2019 - 2024. All rights reserved.