2016-03-30 11 views
3

Ich habe Probleme, direkte Geschwister der Hauptreihe zu wählen. Zum Beispiel ist meine Daten, die ich filtern müssen:MySQL: Get direkte Geschwister der Zeile

+------+------------+------------+ 
| id | from  | to   | 
+------+------------+------------+ 
| 2265 | 2016-03-30 | 2016-04-09 | 
| 1420 | 2016-03-30 | 2016-04-11 | 
| 2261 | 2016-03-30 | 2016-04-12 | 
| 2262 | 2016-04-01 | 2016-04-12 | 
| 1296 | 2016-04-01 | 2016-04-24 | 
| 1053 | 2016-04-01 | 2016-05-01 | 
| 2302 | 2016-04-30 | 2016-05-24 | 
| 2025 | 2016-05-14 | 2016-06-06 | 
| 2392 | 2016-05-20 | 2016-05-28 | 
| 2033 | 2016-05-21 | 2016-06-08 | 
| 2389 | 2016-05-25 | 2016-06-09 | 
+------+------------+------------+ 

Alles was ich brauche ist Zeile auszuwählen und es ist direkt Geschwister von Min-/Max-Terminen. Zum Beispiel sollte Ergebnis sein:

+------+------------+------------+ 
| id | from  | to   | 
+------+------------+------------+ 
| 1296 | 2016-04-01 | 2016-04-24 | 
| 1053 | 2016-04-01 | 2016-05-01 | 
| 2302 | 2016-04-30 | 2016-05-24 | 
+------+------------+------------+ 

Wo Reihe 1053 ist die „Haupt“ Reihe.

Ich weiß, es ist etwas mit MIN und MAX Funktionen, aber ich kann nicht herausfinden, wie man es benutzt. Ich könnte es in meiner App tun, aber ich würde es lieber in SQL wegen der Leistung tun.

Antwort

1

Es scheint, dass Sie so etwas wie die folgende Abfrage wollen:

SELECT m.* 
FROM mytable AS m 
JOIN (
    SELECT id, 
     (SELECT id 
      FROM mytable AS t2 
      WHERE t1.id <> t2.id AND t1.`to` >= t2.`to` 
      ORDER BY `to` DESC, `from` DESC LIMIT 1) AS prev_id, 
     (SELECT id 
      FROM mytable AS t3 
      WHERE t1.id <> t3.id AND t1.`to` <= t3.`to` 
      ORDER BY `to`, `from` LIMIT 1) AS next_id   
    FROM mytable AS t1 
    WHERE id = 1053 
) AS t ON m.id IN (t.id, t.prev_id, t.next_id) 

Die obige Abfrage verwendet zwei korrelierte Unterabfragen, um vorherigen und nächste Aufzeichnungen in Bezug auf den Datensatz den angegebenen id-Wert zu erhalten .

Demo here

+0

Ich denke, Sie haben Recht, aber ich muss es testen. Es gibt einen Datensatz mit einem 'to'' Wert, der kleiner als die vorherige Zeile ist, aber wegen' '' '- Datum ist er unten. Ich denke also, ich sollte den '' '' 'Wert weglassen, solange' 'from'' anders ist. – p3le

+0

Ich weiß nicht, wie man Kommentare bearbeitet, also poste ich ein anderes .. Ich habe ein kleines Update für deine Antwort mit Bedingungsanweisung und Abfrage um '' from'' Wert, was wichtiger ist als '' to''. [Editierte Demo hier] (http://sqlfiddle.com/#!9/02d83/23) – p3le

1

ist hier ein Verfahren unter Verwendung von user variable.

select t1.id, t1.from, t1.to 
from 
    (select *, @rn1 := @rn1 + 1 as row_num from t 
     cross join (select @rn1 := 0) p1) t1 
    cross join (select @target := 
     (select t2.row_num 
     from (select *, @rn2 := @rn2 + 1 as row_num from t 
      cross join (select @rn2 := 0) p2) t2 
     where t2.id = 1053) 
    ) p3 
where t1.row_num in (@target-1, @target, @target+1); 

Um es auf den Tisch zu verwenden, ersetzen t Ihren eigenen Tabellennamen.