2011-08-11 8 views
8

Mam następujące dane w jednej tabeli:MySQL - Pokaż par rekord w jednym rekordzie

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 

Te dane są sortowane chronologicznie, stosując pole DateTime. Chciałbym pokazać te Record „pary” jako 1 rzędzie, tak jak poniżej:

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 

Istnieje kilka zastrzeżeń: Jeśli nie ma Type1, aby rozpocząć, a następnie pokazać NULL w polu Type1Km Powstały stołów. Podobnie, jeśli nie ma końca Typ2, pokaż NULL w polu "Type2Km records.

Jak mogę to zrobić?

+0

Trudnym elementem jest dołączenie do czasu z typem 1 przy następnym wpisywaniu tekstu 2. Jeśli są 2 typy 1 "z rzędu", to Type2Km powinno mieć wartość zerową, prawda? – MPelletier

+0

@ Melletier - poprawne (jest to mało prawdopodobne, ale byłoby korzystne, gdyby rozwiązanie to wzięło pod uwagę) – Simon

+0

Byłbym o wiele łatwiejszy do rozwiązania, gdyby ta tabela miała kolumnę z automatyczną inkrementacją, która łączyłaby X z X + 1 dla test różnicowy ... Czy istnieje, a po prostu nie przedstawiono powyżej? – DRapp

Odpowiedz

4

Niestety, MySQL brakuje FULL OUTER JOIN, więc będziesz musiał UNION dwa zestawy razem.

Otrzymasz informacje o przypadkach, w których istnieje Type1Km, niezależnie od tego, czy ma to miejsce, czy nie: Type2Km.

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 

Teraz potrzebujemy przypadków, w których Type1Km nie istnieje.

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 tym razem, i masz pożądany rezultat:

(
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` 

Aktualizacja

w moim poprzednim zapytaniu, zapomniałem stanowią o „typ 2 "zapisz na samym początku. Zaktualizowano, aby to uwzględnić. Oto wyniki uzyskać:

danych w times tabeli:

+----------+------+------------+ 
| 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 | 
+----------+------+------------+ 

Wyniki zapytania:

+-----------+---------+---------+ 
| 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 dla UNION. Też o tym myślałem :) – MPelletier

0

Jeśli możesz, zmienić strukturę tabeli mieć type1km i type2km, a następnie zaktualizuj po dodaniu km lub po prostu podsumuj przy wyborze.

0

To może działać

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'); 

i zakładając grupę przez godzinę, a także nic nie warte Twojej przykład wyniki nie są dokładne

Aby lepiej wyjaśnić, co to zabawny zapytania

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 
Powiązane problemy