我需要加入两个表并仅获取最新记录。这是基本形式:
table1.id | table1.region | table1.important_col1
1 | NORTH AMERICA | abc
2 | CHINA | def
2 | NORTH AMERICA | hij
table2.id | table2.region | table2.transaction_date | table2.important_col2
1 | NORTH AMERICA | 2/13/2019 | xyz
1 | NORTH AMERICA | 1/13/2019 | zzz
1 | NORTH AMERICA | 12/13/2018 | xxx
期望的结果:
1 | NORTH AMERICA | 2/13/2019 | abc | xyz
我想使用this answer但似乎我不能使用它,如果我需要分组然后按降序日期排序。我将需要右侧多列中的信息,但不要在左侧有重复的行。
右手边每个id最多可以有100个记录,但我只需要一些现在可用的东西。提前致谢。
编辑:我还需要在其他标准上过滤右侧,这样一个简单的MAX(table2.transaction_date)
将无法正常工作。
你可以使用内部窗口函数过滤你的表,我在这个例子中使用了LAG
,但你可以使用ROW_NUMBER并过滤几个记录。使用滑动窗口不会更改记录数或计为SQL聚合,即使用where
而不是使用having
进行过滤。
SELECT
t1.id
,t2.transaction_date
,t1.region
,t1.col1
,t2.important_col2
FROM table1 AS t1
OUTER APPLY (
SELECT
id
,transaction_date
,LAG(transaction_date,1) over (partition by id order by transaction_date desc) as prev_td
,important_col2
FROM table2
-- WHERE filter_by_col=1 -- additonal "right side" filtering
) as t2
where t1.id = t2.id
and t2.prev_td is null
输出:
1 2019-02-13 00:00:00.000 NORTH AMERICA abc xyz
我用它来测试上面的查询:
create table table1
(id int,
region varchar(30),
col1 varchar(100));
insert into table1
values (1 ,'NORTH AMERICA' ,'abc'),
(2,'CHINA','def'),
(2,'NORTH AMERICA','hij');
create table table2
(id int,
region varchar(30),
transaction_date datetime,
important_col2 varchar(100))
insert into table2
values
(1 ,'NORTH AMERICA',convert(datetime, '02/13/19', 1),'xyz'),
(1 ,'NORTH AMERICA',convert(datetime, '01/13/19',1),'zzz'),
(1 ,'NORTH AMERICA',convert(datetime, '12/13/18',1),'xxx')
试试这种方式:
select table11.id, table1.region, max(table2.transaction_date) transaction_date
from table1
inner join table2
on table1.id = table2.id
group by table1.id, table1.region
如果table2
中有更多列(交易日期除外),您想要显示,那么单独聚合无法解决您的问题。
在MySQL 8.0中,您可以使用窗口函数ROW_NUMBER()来标识最新的事务记录,如下所示:
SELECT x.*
FROM (
SELECT
t1.*,
t2.*,
ROW_NUMBER() OVER(PARTITION BY t2.region ORDER BY t2.transaction_date DESC) rn
FROM table1 t1
INNER JOIN table2 t2 ON t1.region = t2.region
) x
WHERE x.rn = 1
在早期版本的MySQL中,一种解决方案是添加带有相关子查询的NOT EXISTS
,以确保我们加入当前区域的最新事务:
SELECT t1.*, t2.*
FROM table1 t1
INNER JOIN table2 t2
ON t1.region = t2.region
AND NOT EXISTS (
SELECT 1
FROM table2
WHERE region = t2.region AND transaction_date > t2.transaction_date
)