Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: SQL Rekordy których nie ma
Forum PHP.pl > Forum > Bazy danych
kinski
Mam tabelę z zakresami: w jednej kolumnie jest początek zakresu, a w drugiej - koniec zakresu.
Np Kolumna A Kolumna B Zakres
1 4 4
7 10 4
16 23 8
Jak można z bazy wydobyć zakresy między moimi rekordami, czyli w tym przykładzie 5-6 i 11-15?
nospor
Spróbuj wyrazić się jaśniej. i co to za kolumna Zakres. I skąd ci sie wziely wartości: 5-6 i 11-15 (wytlumacz)
kinski
Spróbuj wyrazić się jaśniej. i co to za kolumna Zakres. I skąd ci sie wziely wartości: 5-6 i 11-15 (wytlumacz)

Zakres = KolumnaB - KolumnaA + 1, czyli ilość wszystkich numerów w danym zakresie. Wartości 5-6 i 11-15 to te, których nie ma w zakresach, a chcę je znaleźć
nospor
Dzięki za wyjaśnienia. Teraz wszystko jasne.

No to chyba się tego nie da zapytaiem zrobić. Będziesz chyba musiał to w php zrobić.
kinski
Ale jak? Czy mozesz mi pomoc?
nospor
a czy te zakresy mogą nachodzic na siebie? tzn.czy moze zaisteniec tak sytuacja:
1 4 4
2 10 11
8 12 5
?
kinski
Nie mogą, każdy zakres następuje nie wcześniej niż po końcu poprzedniego.
nospor
No dobra. napisalem skrypcik:
  1. <?php
  2.  
  3. $zakresy = array();
  4. $zakresy[0]['begin'] = 1;
  5. $zakresy[0]['end'] = 4;
  6. $zakresy[1]['begin'] = 7;
  7. $zakresy[1]['end'] = 10;
  8. $zakresy[2]['begin'] = 16;
  9. $zakresy[2]['end'] = 23;
  10. $size = count($zakresy);
  11. $missing = array();
  12. $in = 0;
  13. for ($i = 0; $i < $size - 1; $i++ )
  14. {
  15. if ($zakresy[$i]['end']+< $zakresy[$i+1]['begin'] )
  16. {
  17.  
  18. $missing[$in]['begin'] = $zakresy[$i]['end']+1;
  19. $missing[$in]['end'] = $zakresy[$i+1]['begin']-1;
  20. $in++;
  21. }
  22. }
  23. foreach ($missing as $zakres)
  24. {
  25. echo &#092;"{$zakres['begin']} - {$zakres['end']} <br>\";
  26. }
  27.  
  28.  
  29. ?>


twoim zdaniem będzie pobrać z bazy swoje zakresy i wpisać je do tablicy $zakresy. CHyba umiesz pobierać dane z bazy? Jak nie to poczytaj se mysql_query() i mysql_fetch_array().

MOżesz również generować brakujace zakresy na bieżąco podczas pobierania danych z bazy. Bedziesz musial jednak ten skrypt wówczas troche zmodyfikowac. Powodzenia smile.gif
SongoQ
Ja bym zrobil na zasadzie zlaczenia LEFT JOIN i wykuczyl te rzeczy ktore sie powtarzaja. Wtedy dostajemy te wartosci ktore nie wystepuja.
nospor
@SongoQ zaintrygowales mnie biggrin.gif . Aczkolwiek rozwiń swoją myśl bo jakoś nie zakumałem Twej logiki. Jakoś tego nie widzę. Co z tego ze wykluczysz jakieś rekordy? co to ma do nie istniejących liczb?
SongoQ
@nospor Chodzilo mi o cos takiego.

  1. SELECT
  2. (t1.b + 1) AS aa,
  3. (t1.a - 1) AS bb
  4. FROM tabela t1
  5. LEFT JOIN tabela t2 ON (t1.a = t2.b + 1)
  6. WHERE t2.b IS NULL


Zwraca przedzialy, tylko trzeba uwzglednic dolny zakres. Pisalme szybko wiec moglem jeszce czegos nie uwzglednic.
nospor
@SongoQ wow, a ja glupi skrypt w php pisalem (może komus sie przyda). Muszę czasami jednak przemyśleć sql a potem rezać skrypty biggrin.gif . Twój sql dziala. Otrzymalem takie wyniki:
5 0
11 6
24 15

Wystarczy teraz na krzyż polaczyc i sie otrzyma przedzialy 5-6, 11-15
SongoQ
Cytat
Wystarczy teraz na krzyż polaczyc i sie otrzyma przedzialy 5-6, 11-15

No tak, zastanawiam sie czy nie dalo by sie odrazu bez zadnych podselektow zrobic.
kinski
Czegoś nie rozumiem... Czy mogę połączyć tabelę ze samą sobą? U mnie to wygląda tak:

SELECT
(tabela1.ostatni_numer + 1) AS ostatni_numer,
(tabela1.pierwszy_numer - 1) AS pierwszy_numer
FROM tabela1
LEFT JOIN tabela1 ON (tabela1.pierwszy_numer = tabela1.ostatni_numer + 1)
WHERE tabela1.ostatni_numer IS NULL

I nie działa. Gdzie zrobiłem błąd?
nospor
NIee robisz aliasów . Zobacz, że w rozwiązaniu @SongoQ są aliasy, czyli
...tabela t1... tabela t2....
SongoQ
  1. SELECT
  2. (tabela1.ostatni_numer + 1) AS ostatni_numer,
  3. (tabela1.pierwszy_numer - 1) AS pierwszy_numer
  4. FROM tabela1 t1
  5. LEFT JOIN tabela1 t2 ON (t1.pierwszy_numer = t2.ostatni_numer + 1)
  6. WHERE t2.ostatni_numer IS NULL
kinski
Zastosowałem Twoe zapytanie SongoQ, ale wyskoczył mi komunikat, że nie może znaleźć kolumny ostatni_numer
nospor
kolega @SongoQ jedynie zmodyfikowal Twoj kod. A masz wogole kolumne ostatni_numer?

Jak masz to spróbuj ewentualnie tak:
  1. SELECT
  2. (tabela1.ostatni_numer + 1) AS ostatni_numer2,
  3. (tabela1.pierwszy_numer - 1) AS pierwszy_numer2
  4. FROM tabela1 t1
  5. LEFT JOIN tabela1 t2 ON (t1.pierwszy_numer = t2.ostatni_numer + 1)
  6. WHERE t2.ostatni_numer IS NULL
kinski
Kolumnę ostatni_numer mam na pewno! :-) Poza tym Jak robię samego selecta to jest ok - Problem pojawia się kiedy do zapytania dodam złączenie.
SongoQ
mama pomylka.

ma byc (t1.ostatni_numer + 1) AS ostatni_numer2,
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.