我在Mysql中有Table,我需要能够基于最接近的时间戳与匹配的行[可能早于或等于或大于另一行的时间戳[但最接近]的行连接数据,用户名]。
这是示例数据Mysql表:
+----+----------+---------+----------+---------------------+
| Id | userName | Browser | Platform | TS |
+----+----------+---------+----------+---------------------+
| 1 | abc | Firefox | NULL | 2006-10-05 11:55:45 |
| 2 | xyz | Chrome | NULL | 2007-10-07 12:34:17 |
| 3 | mnp | Safari | NULL | 2008-10-09 08:19:37 |
| 4 | abc | Safari | NULL | 2010-10-13 04:28:14 |
| 5 | abc | NULL | Windows | 2006-01-01 12:02:45 |
| 6 | xyz | NULL | Linux | 2007-01-01 12:01:20 |
| 7 | mnp | NULL | MAC | 2008-01-01 12:02:29 |
| 8 | abc | NULL | MAC | 2010-03-09 13:06:59 |
+----+----------+---------+----------+---------------------+
我需要如下输出:
+----+----------+---------+----------+---------------------+
| Id | userName | Browser | Platform | TS |
+----+----------+---------+----------+---------------------+
| 1 | abc | Firefox | Windows | 2006-10-05 11:55:45 |
| 2 | xyz | Chrome | Linux | 2007-10-07 12:34:17 |
| 3 | mnp | Safari | MAC | 2008-10-09 08:19:37 |
| 4 | abc | Safari | MAC | 2010-10-13 04:28:14 |
| 5 | abc | Firefox | Windows | 2006-01-01 12:02:45 |
| 6 | xyz | Chrome | Linux | 2007-01-01 12:01:20 |
| 7 | mnp | Safari | MAC | 2008-01-01 12:02:29 |
| 8 | abc | Safari | MAC | 2010-03-09 13:06:59 |
+----+----------+---------+----------+---------------------+
任何人都可以建议需要获取所需输出的mysql查询
答案 0 :(得分:1)
如果您有支持lead() over()
的MySQL v8或MariaDb
CREATE TABLE mytable( Id INT ,userName VARCHAR(10) ,Browser VARCHAR(9) ,Platform VARCHAR(10) ,TS timestamp );
INSERT INTO mytable(Id,userName,Browser,Platform,TS) VALUES > > > > > (1,'abc','Firefox',NULL,'2006-10-05 11:55:45'); , (2,'xyz','Chrome',NULL,'2007-10-07 12:34:17'); , (3,'mnp','Safari',NULL,'2008-10-09 08:19:37'); , (4,'abc','Safari',NULL,'2010-10-13 04:28:14') , (5,'abc',NULL,'Windows','2006-01-01 12:02:45') , (6,'xyz',NULL,'Linux','2007-01-01 12:01:20') , (7,'mnp',NULL,'MAC','2008-01-01 12:02:29') , (8,'abc',NULL,'MAC','2010-03-09 13:06:59')
with cte as ( select * , coalesce(lead(ts) over(order by ts),current_time) nxt from mytable ) select id , username , coalesce(browser,(select browser from cte where t.ts between cte.ts and cte.nxt limit 1 )) browser , coalesce(platform,(select platform from cte where t.ts between cte.ts and cte.nxt limit 1 )) platform , ts , nxt from cte t
id | username | browser | platform | ts | nxt -: | :------- | :------ | :------- | :------------------ | :------------------ 5 | abc | null | Windows | 2006-01-01 12:02:45 | 2006-10-05 11:55:45 1 | abc | Firefox | Windows | 2006-10-05 11:55:45 | 2007-01-01 12:01:20 6 | xyz | Firefox | Linux | 2007-01-01 12:01:20 | 2007-10-07 12:34:17 2 | xyz | Chrome | Linux | 2007-10-07 12:34:17 | 2008-01-01 12:02:29 7 | mnp | Chrome | MAC | 2008-01-01 12:02:29 | 2008-10-09 08:19:37 3 | mnp | Safari | MAC | 2008-10-09 08:19:37 | 2010-03-09 13:06:59 8 | abc | Safari | MAC | 2010-03-09 13:06:59 | 2010-10-13 04:28:14 4 | abc | Safari | MAC | 2010-10-13 04:28:14 | 2018-10-02 08:11:44
db <>提琴here
答案 1 :(得分:0)
如果您使用的是较早版本的mysql,则该版本不支持分析功能:
(这应该等同于@Used_By_Already的其他答案)
SELECT
t2.Id,
t2.userName,
COALESCE(t2.Browser, t2.other_Browser),
COALESCE(t2.Platform, t2.other_Platform),
t2.TS,
t2.other_TS
from (
SELECT
t.*,
IF (t.Id = @prev_id, @rankk:=@rankk+1, @rankk:=0) as rankk,
@prev_id := t.Id
from (
select
a.Id, a.userName, a.Browser , a.Platform, a.TS,
b.Id as other_Id, b.Browser as other_Browser , b.Platform as other_Platform, b.TS as other_TS,
ABS(TIMESTAMPDIFF(SECOND, a.TS, b.TS)) as time_diff
from mytable a join mytable b on a.userName = b.userName and a.Id <> b.Id
order by a.Id, ABS(TIMESTAMPDIFF(SECOND, a.TS, b.TS)))
t join (select @prev_Id:=NULL, @rankk:=0) c
) t2
WHERE rankk=0