Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL]Pobieranie rekordu z bazy zależne od innego rekordu
Forum PHP.pl > Forum > Przedszkole
marekdominikowski
Cześć

Mam tabelę, w której w jednej z kolumn znajdują się jakieś powtarzające się wartości. Niech to będą na przykład A, B, C, D, E, F. Potrzebuję pobrać np. rekordy A, ale tylko te, które występują bezpośrednio po np. B albo po np. B lub C.

Na przykład:

1. B
2. A
3. D
4. A
5. C
6. A
7. B
8. A

Dla "A po B" zapytanie zwróci rekordy 2 i 8.
Dla "A po B lub C" zapytanie zwróci rekordy 2, 6 i 8.

Jak takie zapytanie skonstruować?
nospor
Jesi chcesz to zrobic tylko na poziomie baze, to musisz skorzystac ze zmiennych w mysql.

W zmiennej przechowujesz aktualną wartosc, a przy nastepnym rekordzie porownujesz ją do B lub C. Ot i wszystko smile.gif
mmmmmmm
  1. /*
  2. create table xxc(id int, x varchar(10));
  3. insert into xxc values(1, 'B'),(2, 'A'), (3, 'D'),(4, 'A'), (5, 'C'), (6, 'A'), (7, 'B'), (8, 'A');
  4. */
  5.  
  6. -- 1.
  7. SELECT x1.id FROM xxc x1 JOIN xxc x2 ON x1.id=x2.id+1
  8. WHERE x1.x='A' AND x2.x IN ('B');
  9. -- 2.
  10. SELECT x1.id FROM xxc x1 JOIN xxc x2 ON x1.id=x2.id+1
  11. WHERE x1.x='A' AND x2.x IN ('B', 'C');

Tak na szybko... Dlatego MUSI zachodzić warunek ciągłości id.
nospor
Moja wersja nie wymaga ciaglosci wink.gif
mmmmmmm
Moja też nie...:
  1. SELECT x1.id FROM xxc x1 JOIN (SELECT x, (SELECT Min(id) FROM xxc WHERE xxc.id>t.id) id FROM xxc t) x2 ON x1.id=x2.id
  2. WHERE x1.x='A' AND x2.x IN ('B', 'C')

Tamta była pisana "na szybko" smile.gif
nospor
Moja jest wydajniejsza, wymaga tylko i wylacznie jednego glownego SELECT a nie jakis dzikich kombinacji wink.gif

Twoja ma jednak jedną wielka zalete: jest podana na tacy, podczas gdy moją autor musi sam sklecic wink.gif Podejrzewam wiec, ze twoja w oczach autora jest lepsza.
mmmmmmm
To raczej taka 'wprawka' dla samego siebie... Staram się wszystko rozwiązać via SQL. I to najlepiej w bazie. Na razie nie mam z tym problemów... Co więcej - piszę w czystym ANSI SQL. Powyższe zadziała zarówno w MySQL, jak i postgreSQL. Jakbym miał "typowane" to wtedy bym optymalizował...
nospor
Ale moje tez jest na czystej bazie. zero php czy innych takich pierdol smile.gif
marekdominikowski
Dzięki za odpowiedzi. Niezaprzeczalnym plusem rozwiązania mmmmmmm jest podanie go na tacy smile.gif. Lepsza wydajność rozwiązania nospor wydaje się jednak być ważniejsza. Ma jednak faktycznie taki minus, że muszę je sam zapisać. Jest to minus, jak na razie dla mnie, nieprzeskakiwalny sad.gif. Jeszcze przez jakiś czas mogę pozostać przy starym rozwiązaniu w PHP. Z dużej tabeli pobieram sobie rekordy według pewnych kryteriów i dopiero ten wynik przetwarzam sobie kodem o takim schemacie:
  1. <?php
  2. $tablica = array('B', 'A', 'D', 'A', 'C', 'A', 'C', 'A', 'D', 'A', 'D', 'A');
  3.  
  4. foreach ($tablica as $wiersz) {
  5.  
  6. if ($wiersz == 'C') {
  7. $czy = 'yes';
  8. } else {
  9. if ($wiersz == 'A' && $czy == 'yes')
  10. echo $wiersz.'<br />';
  11. $czy = 'no';
  12. }
  13. }
  14. ?>

Jak dotąd ilość tych rekordów do przetworzenia jest niewielka więc wydajność takiego rozwiązania nie ma dla mnie większego znaczenia. Problem pojawi się gdy będę chciał rozszerzyć kryteria ich wyboru i znacznie wzrośnie ich ilość. Dlatego chciałem zdać te obliczenia na bazę danych. Niestety, poza podstawowymi poleceniami SQL niewiele z niego kojarzę wink.gif.
nospor
  1. SET @zmprev=NULL,@zm2=NULL;
  2. SELECT * FROM (SELECT T.*, @zmprev:=@zm2 AS zmprev, @zm2:=POLE FROM T) podsel WHERE podsel.POLE='A' AND (podsel.zmprev = 'B' || podsel.zmprev = 'C')
marekdominikowski
Bardzo Wam dziękuję. Oba rozwiązania bardzo mi pomogą..
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.