我需要连接两个表并仅获取最新记录。这是基本形式:
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)
无法正常工作。
答案 0 :(得分:1)
您可以使用内部窗口函数来过滤表,在此示例中,我使用了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')
答案 1 :(得分:0)
以这种方式尝试:
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
答案 2 :(得分:0)
如果您还希望在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
)