我有一张2000万行的表。
每一行代表一天+客户。
并非所有日期都以行表示。
我需要获取一系列日期,比如2015-01-01到2016-01-01表,这将为每个客户提供距离上方最近的行到2015-01-01,并且最接近低于2016-01-01
表:
期望的结果:
总而言之,这是从同一个表格中划分为一行的两行。
只需选择和加入即可。查询此数据的正确方法是什么?
答案 0 :(得分:0)
一种方法是使用两个从属子查询 - 但这可能效率不高,MySql在优化相关子查询方面不是很聪明。:
SELECT client,
date as date1,
( SELECT date FROM table t2
WHERE t1.client = t2.client
AND t2.date > t1.date
ORDER BY t2.date LIMIT 1
) as date2,
random As random1,
( SELECT random FROM table t2
WHERE t1.client = t2.client
AND t2.date > t1.date
ORDER BY t2.date LIMIT 1
) as random2
FROM table t1
您可以在table(client, date)
上创建多列索引,以加快此查询速度。
答案 1 :(得分:0)
有几种方法。也许最简单的方法是使用substring_index()
/ group_concat()
hack:
select client, min(date) as date1, max(date) as date2,
substring_index(group_concat(random order by date), ',', 1) as random1,
substring_index(group_concat(random order by date desc), ',', 1) as random2
from t
where date >= '2015-01-01' and
date < '2016-01-01'
group by client;
根据您的示例数据,这应该运行良好。
更传统的方法是使用聚合和连接:
select c.client, c.date1, c.date2, t1.random as random1, t2.random as random2
from (select t.client, min(date) as date1, max(date) as date2
from t
where date >= '2015-01-01' and date < '2016-01-01'
group by client
) c join
t t1
on c.client = t1.client and c.date1 = t1.date join
t t2
on c.client = t2.client and c.date2 = t2.date;
这也可以更容易地添加两个以上的数据列。