SQL连接为时间和标识符添加缺少的数据

时间:2015-05-18 12:27:42

标签: mysql sql join

我有两张桌子: 表a包含每c_id每分钟的值。 (如果缺少c_id和分钟的数据 - 缺少行。)

表a:

---------------------------------
| c_id  | TIME_SEC    | C_VALUE |
---------------------------------
|    1  | 1431943200  |      10 |
---------------------------------
|    1  | 1431943260  |      11 |
---------------------------------
|    2  | 1431943200  |      12 |
---------------------------------

包含所有分钟的表时间:

------------
| TIME_SEC |
------------
|1431943140|
------------
|1431943200|
------------
|1431943260|
------------
|1431943320|
------------

我希望在给定的c_id之间获取包含缺失数据的所有数据。例如: c_id在(1,2)和TIME_SEC之间1431943140和1431943320

预期结果是:

---------------------------------
| c_id  | TIME_SEC    | C_VALUE |
---------------------------------
|    1  | 1431943140  |    null |
---------------------------------
|    1  | 1431943200  |      10 |
---------------------------------
|    1  | 1431943260  |      11 |
---------------------------------
|    1  | 1431943320  |    null |
---------------------------------
|    2  | 1431943140  |    null |
---------------------------------
|    2  | 1431943200  |      12 |
---------------------------------
|    2  | 1431943260  |    null |
---------------------------------
|    2  | 1431943320  |    null |
---------------------------------

向表a添加缺失数据不是一种选择,因为它会增加大量数据。

我尝试使用这个SQL:

select * 
from 
(
select * from 
a where c_id IN ( 1,2 ) AND TIME_SEC between 1431943140 and 1431943320
) m 
right join times t
on (m.TIME_SEC = t.TIME_SEC);

但它会全局返回每分钟丢失的数据 - 对于所有c_id:

---------------------------------
| c_id  | TIME_SEC    | C_VALUE |
---------------------------------
| null  | 1431943140  |    null |
---------------------------------
|    1  | 1431943200  |      10 |
---------------------------------
|    1  | 1431943260  |      11 |
---------------------------------
|    2  | 1431943200  |      12 |
---------------------------------
| null  | 1431943320  |    null |
---------------------------------

任何帮助?

2 个答案:

答案 0 :(得分:1)

创建所需c_id和times的派生表,然后LEFT JOIN到值:

select m.c_id, m.TIME_SEC, a.C_VALUE
from (
  SELECT DISTINCT a.c_id, t.TIME_SEC
  FROM a
  CROSS JOIN times t
  where a.c_id IN ( 1,2 ) AND t.TIME_SEC between 1431943140 and 1431943320
) m
LEFT OUTER JOIN a
  ON m.c_id=a.c_id
  AND m.TIME_SEC=a.TIME_SEC;

答案 1 :(得分:0)

首先使用cross join生成所有行。然后引入其他值:

select c.c_id, t.time_sec, a.c_value
from (select 1 as c_id union all select 2) c cross join
     (select distinct time_sec
      from a
      where c_id in (1, 2) and time_sec between 1431943140 and 1431943320
     ) t left join
     a
     on a.c_id = c.c_id and a.time_sec = t.time_sec;

编辑:

如果您想使用times表:

select c.c_id, t.time_sec, a.c_value
from (select 1 as c_id union all select 2) c cross join
     times t left join
     a
     on a.c_id = c.c_id and a.time_sec = t.time_sec;

我不确定是否需要where子句限制时间。