Select 在一些 "left joins" 之后用最新的日期时间字段完成行
Select complete row with the latest datetime field after some "left joins"
是的,好像回答了很多次,但我都试过了。
最相似的Whosebug的post肯定是:
但是这里的主要区别是我需要在之前执行一些左连接之后进行分组。
情况是这样的:
我有 3 个 table(交易、支持和 transaction_support 链接前 2 个 table)
create TABLE `transaction`
(
id INT,
date_time DATE,
notes TEXT,
PRIMARY KEY (id)
);
create TABLE `support`
(
id int,
support_number int ,
PRIMARY KEY (id)
);
create TABLE `transaction_support`
(
id INT,
transaction_id int,
support_id int,
PRIMARY KEY (id),
FOREIGN KEY (transaction_id) REFERENCES transaction(id),
FOREIGN KEY (support_id) REFERENCES support(id)
);
INSERT INTO `support` values (1, 1111);
INSERT INTO `support` values (2, 2222);
INSERT INTO `support` values (3, 3333);
INSERT INTO `transaction` values (1, '1996-06-28 00:00:00', 'Old data, we shouln''t see it');
INSERT INTO `transaction` values (2, '1996-07-16 00:00:00', 'Old data, we shouln''t see it');
INSERT INTO `transaction` values (3, '2001-04-10 00:00:00', 'Old data, we shouln''t see it');
INSERT INTO `transaction` values (4, '2001-05-14 00:00:00', 'Lastest data from Danny');
INSERT INTO `transaction` values (5, '2001-05-14 00:00:00', 'Lastest data from John');
INSERT INTO `transaction` values (6, '2001-04-10 00:00:00', 'Old data, we shouln''t see it');
INSERT INTO `transaction_support` values (487131, 1, 2);
INSERT INTO `transaction_support` values (488504, 2, 2);
INSERT INTO `transaction_support` values (751126, 3, 2);
INSERT INTO `transaction_support` values (758188, 4, 2);
INSERT INTO `transaction_support` values (4444, 5, 3);
INSERT INTO `transaction_support` values (4445, 6, 3);
这是一个尝试的请求:
SELECT s.id AS s_id, t.*, MAX(t.date_time) AS `this date is good`
FROM support AS s
LEFT JOIN transaction_support AS ts ON ts.support_id = s.id
LEFT JOIN transaction AS t ON ts.transaction_id = t.id
GROUP BY ts.support_id
再次尝试子查询:
SELECT s.id as support_id, t.*, sub.*
FROM support AS s
LEFT JOIN transaction_support AS ts ON ts.support_id = s.id
LEFT JOIN transaction AS t ON ts.transaction_id = t.id
LEFT JOIN (
SELECT ts.support_id AS `sub_support_id`,
t.id AS `sub_transaction_id`,
MAX(t.date_time) AS `sub_last_date`
FROM transaction_support AS ts
LEFT JOIN transaction AS t ON ts.transaction_id = t.id
GROUP BY ts.support_id
) sub ON ts.support_id = sub.sub_support_id AND t.date_time = sub.sub_last_date
GROUP BY s.id
预期结果为:
|support_id | transaction_id | transaction_notes | transaction_date|
|-----------|----------------|-------------------------|-----------------|
| 1 | null | null | null |
| 2 | 4 | Lastest data from Danny | 2001-05-14 |
| 3 | 5 | Lastest data from John | 2001-05-14 |
我尝试了很多请求,有和没有子查询,但到目前为止,当我“分组”支持 ID 时,我从未从事务 table 中获得所有最新数据。
但我很确定我需要一个子查询...
这是一个 fiddle : http://sqlfiddle.com/#!9/adc611/20
一些其他类似的 post 我试过了 :
- GROUP BY with MAX(DATE)
- SQL select only rows with max value on a column
- MySQL select MAX(datetime) not returning max value
如果有人能帮我找出解决办法...谢谢! :)
对于您的 MySql 版本,没有简单的解决方案。
您可以使用 NOT EXISTS 获取每个 support_id
的最新 date_time
的数据,并将 support
加入该结果集:
SELECT s.id AS support_id,
x.id AS transaction_id,
x.notes AS transaction_notes,
x.date_time AS transaction_date
FROM support AS s
LEFT JOIN (
SELECT ts.support_id, t.id, t.notes, t.date_time
FROM transaction_support ts INNER JOIN transaction t
ON ts.transaction_id = t.id
WHERE NOT EXISTS (
SELECT 1
FROM transaction_support ts2 INNER JOIN transaction t2
ON ts2.transaction_id = t2.id
WHERE ts2.support_id = ts.support_id AND t2.date_time > t.date_time
)
) AS x ON x.support_id = s.id
参见demo。
结果:
> support_id | transaction_id | transaction_notes | transaction_date
> ---------: | -------------: | :---------------------- | :---------------
> 1 | null | null | null
> 2 | 4 | Lastest data from Danny | 2001-05-14
> 3 | 5 | Lastest data from John | 2001-05-14
如果您想要每个支持的最新交易,一个选项是在 left join
的 on
子句中使用子查询进行过滤:
select s.*, t.*
from support s
left join (
select t.*, ts.support_id
from transaction_support ts
inner join transaction t
on t.id = ts.transaction_id
and t.date_time = (
select max(t1.date_time)
from transaction_support ts1
inner join transaction t1 on t1.id = ts1.transaction_id
where ts1.support_id = ts.support_id
)
) t on s.id = t.support_id
是的,好像回答了很多次,但我都试过了。
最相似的Whosebug的post肯定是:
情况是这样的:
我有 3 个 table(交易、支持和 transaction_support 链接前 2 个 table)
create TABLE `transaction`
(
id INT,
date_time DATE,
notes TEXT,
PRIMARY KEY (id)
);
create TABLE `support`
(
id int,
support_number int ,
PRIMARY KEY (id)
);
create TABLE `transaction_support`
(
id INT,
transaction_id int,
support_id int,
PRIMARY KEY (id),
FOREIGN KEY (transaction_id) REFERENCES transaction(id),
FOREIGN KEY (support_id) REFERENCES support(id)
);
INSERT INTO `support` values (1, 1111);
INSERT INTO `support` values (2, 2222);
INSERT INTO `support` values (3, 3333);
INSERT INTO `transaction` values (1, '1996-06-28 00:00:00', 'Old data, we shouln''t see it');
INSERT INTO `transaction` values (2, '1996-07-16 00:00:00', 'Old data, we shouln''t see it');
INSERT INTO `transaction` values (3, '2001-04-10 00:00:00', 'Old data, we shouln''t see it');
INSERT INTO `transaction` values (4, '2001-05-14 00:00:00', 'Lastest data from Danny');
INSERT INTO `transaction` values (5, '2001-05-14 00:00:00', 'Lastest data from John');
INSERT INTO `transaction` values (6, '2001-04-10 00:00:00', 'Old data, we shouln''t see it');
INSERT INTO `transaction_support` values (487131, 1, 2);
INSERT INTO `transaction_support` values (488504, 2, 2);
INSERT INTO `transaction_support` values (751126, 3, 2);
INSERT INTO `transaction_support` values (758188, 4, 2);
INSERT INTO `transaction_support` values (4444, 5, 3);
INSERT INTO `transaction_support` values (4445, 6, 3);
这是一个尝试的请求:
SELECT s.id AS s_id, t.*, MAX(t.date_time) AS `this date is good`
FROM support AS s
LEFT JOIN transaction_support AS ts ON ts.support_id = s.id
LEFT JOIN transaction AS t ON ts.transaction_id = t.id
GROUP BY ts.support_id
再次尝试子查询:
SELECT s.id as support_id, t.*, sub.*
FROM support AS s
LEFT JOIN transaction_support AS ts ON ts.support_id = s.id
LEFT JOIN transaction AS t ON ts.transaction_id = t.id
LEFT JOIN (
SELECT ts.support_id AS `sub_support_id`,
t.id AS `sub_transaction_id`,
MAX(t.date_time) AS `sub_last_date`
FROM transaction_support AS ts
LEFT JOIN transaction AS t ON ts.transaction_id = t.id
GROUP BY ts.support_id
) sub ON ts.support_id = sub.sub_support_id AND t.date_time = sub.sub_last_date
GROUP BY s.id
预期结果为:
|support_id | transaction_id | transaction_notes | transaction_date|
|-----------|----------------|-------------------------|-----------------|
| 1 | null | null | null |
| 2 | 4 | Lastest data from Danny | 2001-05-14 |
| 3 | 5 | Lastest data from John | 2001-05-14 |
我尝试了很多请求,有和没有子查询,但到目前为止,当我“分组”支持 ID 时,我从未从事务 table 中获得所有最新数据。
但我很确定我需要一个子查询...
这是一个 fiddle : http://sqlfiddle.com/#!9/adc611/20
一些其他类似的 post 我试过了 :
- GROUP BY with MAX(DATE)
- SQL select only rows with max value on a column
- MySQL select MAX(datetime) not returning max value
如果有人能帮我找出解决办法...谢谢! :)
对于您的 MySql 版本,没有简单的解决方案。
您可以使用 NOT EXISTS 获取每个 support_id
的最新 date_time
的数据,并将 support
加入该结果集:
SELECT s.id AS support_id,
x.id AS transaction_id,
x.notes AS transaction_notes,
x.date_time AS transaction_date
FROM support AS s
LEFT JOIN (
SELECT ts.support_id, t.id, t.notes, t.date_time
FROM transaction_support ts INNER JOIN transaction t
ON ts.transaction_id = t.id
WHERE NOT EXISTS (
SELECT 1
FROM transaction_support ts2 INNER JOIN transaction t2
ON ts2.transaction_id = t2.id
WHERE ts2.support_id = ts.support_id AND t2.date_time > t.date_time
)
) AS x ON x.support_id = s.id
参见demo。
结果:
> support_id | transaction_id | transaction_notes | transaction_date
> ---------: | -------------: | :---------------------- | :---------------
> 1 | null | null | null
> 2 | 4 | Lastest data from Danny | 2001-05-14
> 3 | 5 | Lastest data from John | 2001-05-14
如果您想要每个支持的最新交易,一个选项是在 left join
的 on
子句中使用子查询进行过滤:
select s.*, t.*
from support s
left join (
select t.*, ts.support_id
from transaction_support ts
inner join transaction t
on t.id = ts.transaction_id
and t.date_time = (
select max(t1.date_time)
from transaction_support ts1
inner join transaction t1 on t1.id = ts1.transaction_id
where ts1.support_id = ts.support_id
)
) t on s.id = t.support_id