2011-08-11 1 views
8

内のレコードのペアを表示:MySQLの - 私は1つのテーブルに次のデータを持っている一つのレコード

Time, Type, Kilometers 
12:00, 1, 0.1 
12:30, 2, 0.2 
14:00, 1, 0.4 
15:00, 2, 1.0 
16:00, 1, 1.2 
16:30, 2, 1.5 
16:45, 1, 2.0 

このデータは、DateTimeフィールドを使用して時系列でソートされます。

StartTime, Type1Km, Type2Km 
12:00, 0.1, 0.2 
14:00, 0.4, 1.0 
16:00, 1.2, 1.5 
16:45, 2.0, NULL 

警告のカップルがあります:起動する一切のType1がない場合、その結果のテーブルType1KmフィールドにNULLを示したので、は次のように私は、1行としてこれらのレコードの「ペア」を示したいと思います。同様に、Type2の終了がない場合、レコードのType2KmフィールドにNULLを表示します。

どうすればいいですか?

+0

トリッキーな部分は、次回のタイプでタイプ1の時間に参加しているということです2. 2つのタイプ1の「行内」がある場合、Type2Kmはヌルでなければなりません。 – MPelletier

+0

@MPelletier - 正しい(これは起こりそうもないが、解決策がこれを考慮すれば有益だろう) – Simon

+0

この表にXをX + 1にリンクする自動インクリメント列があれば、ディファレンシャルテスト... 1つだけあり、上に表示されていませんか? – DRapp

答えて

4

残念ながら、MySQLにはFULL OUTER JOINがありません。したがって、UNIONを2組一緒に使用する必要があります。

Type2Kmがそうであるかどうかにかかわらず、Type1Kmが存在する場合があります。

SELECT 
    t1.`Time` as StartTime, 
    t1.`Kilometers` as Type1Km, 
    t2.`Kilometers` as Type2Km 
FROM `times` t1 
LEFT JOIN `times` t2 ON t2.`Type` = 2 
        AND t2.`Time` = (SELECT `Time` FROM `times` 
            WHERE `Time` > t1.`Time` 
            ORDER BY `Time` LIMIT 1) 
WHERE t1.`Type` = 1 

ここで、Type1Kmが存在しない場合が必要です。

SELECT 
    t2.`Time` as StartTime, 
    NULL as Type1Km, 
    t2.`Kilometers` as Type2Km 
FROM `times` t2 
LEFT JOIN `times` t1 ON t1.`Time` = (SELECT `Time` FROM `times` 
            WHERE `Time` < t2.`Time` 
            ORDER BY `Time` DESC LIMIT 1) 
WHERE t2.`Type` = 2 
    AND (t1.`Type` = 2 OR t1.`Type` IS NULL) 

UNION一緒にものを、あなたが希望する結果があります:私の前のクエリで

(
SELECT 
    t1.`Time` as StartTime, 
    t1.`Kilometers` as Type1Km, 
    t2.`Kilometers` as Type2Km 
FROM `times` t1 
LEFT JOIN `times` t2 ON t2.`Type` = 2 
        AND t2.`Time` = (SELECT `Time` FROM `times` 
            WHERE `Time` > t1.`Time` 
            ORDER BY `Time` LIMIT 1) 
WHERE t1.`Type` = 1 

) UNION ALL (

SELECT 
    t2.`Time` as StartTime, 
    NULL as Type1Km, 
    t2.`Kilometers` as Type2Km 
FROM `times` t2 
LEFT JOIN `times` t1 ON t1.`Time` = (SELECT `Time` FROM `times` 
            WHERE `Time` < t2.`Time` 
            ORDER BY `Time` DESC LIMIT 1) 
WHERE t2.`Type` = 2 
    AND (t1.`Type` = 2 OR t1.`Type` IS NULL) 
) 

ORDER BY `StartTime` 

更新

を、私は「2型を持つために考慮するのを忘れました"最初の時点で記録する。そのために更新されました。 timesテーブルで

データ:クエリの

+----------+------+------------+ 
| Time  | Type | Kilometers | 
+----------+------+------------+ 
| 11:00:00 | 2 |  0.1 | 
| 12:00:00 | 1 |  0.1 | 
| 12:30:00 | 2 |  0.2 | 
| 14:00:00 | 1 |  0.4 | 
| 14:30:00 | 1 |  0.8 | 
| 15:00:00 | 2 |  1.0 | 
| 15:30:00 | 2 |  0.2 | 
| 16:00:00 | 1 |  1.2 | 
| 16:30:00 | 2 |  1.5 | 
| 16:45:00 | 1 |  2.0 | 
+----------+------+------------+ 

結果:その後、

+-----------+---------+---------+ 
| StartTime | Type1Km | Type2Km | 
+-----------+---------+---------+ 
| 11:00:00 | NULL |  0.1 | 
| 12:00:00 |  0.1 |  0.2 | 
| 14:00:00 |  0.4 | NULL | 
| 14:30:00 |  0.8 |  1.0 | 
| 15:30:00 | NULL |  0.2 | 
| 16:00:00 |  1.2 |  1.5 | 
| 16:45:00 |  2.0 | NULL | 
+-----------+---------+---------+ 
+0

+1のために。私もそう思っていた:) – MPelletier

0

あなたは、type1kmとtype2kmを持っているあなたのテーブル構造を変更することができた場合は、ここでの結果は、私が手ですkmsを追加するときに更新するか、選択するときに合計するだけです。

0

これは私が時間単位でグループを想定し、また、より良い、この面白いクエリが

何をするかを説明することは何もあなたの例の結果が正確ではない

価値

select 
max(Time), 
substring_index(group_concat(if(type=2,null,Kilometers) order by type),',',1), 
substring_index(group_concat(if(type=1,null,Kilometers) order by type desc),',',1) 
from your_table 
group by date_format(Time, '%H'); 

を働くかもしれません

group_concat(if(type=2,null,Kilometers) order by type -- this is ensure the Kilometers must NOT from type=2 group_concat(if(type=1,null,Kilometers) order by type desc -- this is ensure the Kilometers must NOT from type=1 
関連する問題