SQL - 如何从同一个表中拼接两行

时间:2016-05-01 11:42:15

标签: mysql sql

我有一张2000万行的表。

每一行代表一天+客户。

并非所有日期都以行表示。

我需要获取一系列日期,比如2015-01-01到2016-01-01表,这将为每个客户提供距离上方最近的行到2015-01-01,并且最接近低于2016-01-01

表:

enter image description here

期望的结果:

enter image description here

总而言之,这是从同一个表格中划分为一行的两行。

只需选择和加入即可。查询此数据的正确方法是什么?

2 个答案:

答案 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;

这也可以更容易地添加两个以上的数据列。