Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wyrażenie regularne?
Forum PHP.pl > Forum > Bazy danych > MySQL
poldo
Witam,

Mam pewien nietypowy problem i nie wiem jak go "ugryźć", zaprezentuje na przykładzie o co mi chodzi. Mam a bazie kilka rekordów, zapisanych np. tak:

  1. ID | Numer | ....
  2. 1 | A/1/2012 | ....
  3. 2 | A/5/2012 | ....
  4. 3 | A/21/2012 | ....
  5. 4 | A/101/2012 | ....
  6. 5 | Z/11/2012 | ....


To co muszę wydobyć to maksymalna wartość numeru pomiędzy A/.../2012. Wiem jak wyświetlić (czyli ograniczyć) wyniki do tego czego szukam, ale nie wiem jak zastosować funkcję MAX() w SELECIE by wyświetlał to czego poszukuję. Przykładowo...

  1. SELECT MAX(Numer) FROM `tabela` WHERE Numer REGEXP '(A/)+[0-9]+(/2012)'


...nie zadziała bo zamiast MAX(Numer) musiałbym tutaj zamiast "Numer" wprowadzić jakiś warunek który spowoduje branie pod uwagę tylko tego numeru znajdującego się wewnątrz ciągu, a nie całego ciągu. Dodam że długość ciągu oraz numeru może być różna (dla przykładu jest A/.../2012, ale moż być też np. XYZ/......../2013, itp), dlatego na sztywno nie da się tego określić funkcją SUBSTR(). Ma ktoś pomysł jak mogę wyświetlić maksymalny numer zawierający się w tym przykładzie między A/..../2012 ?
pitu
Nie zadziała z substring?
  1. SELECT MAX(SUBSTRING(Numer, 3, 1)) FROM `tabela` WHERE Numer REGEXP '(A/)+[0-9]+(/2012)'


PS. Nie doczytałem o różnej długości...
poldo
No właśnie, nie może to być na "sztywno", więc SUBSTRING() odpada ;-(
Pawel_W
Trochę naokoło ale powinno działać: http://bytes.com/topic/mysql/answers/510254-order-regex
sazian
a tak
  1. SELECT
  2. MAX(LEFT(sub,locate('/',sub)-1))
  3.  
  4. FROM (
  5. SELECT
  6. substr(numer,locate('/',numer)+1,length(numer)) sub
  7. FROM tabela
  8. ) t
poldo
Cytat(sazian @ 25.11.2012, 12:40:17 ) *
a tak
  1. SELECT
  2. MAX(LEFT(sub,locate('/',sub)-1))
  3.  
  4. FROM (
  5. SELECT
  6. substr(numer,locate('/',numer)+1,length(numer)) sub
  7. FROM tabela
  8. ) t


Heja,

Przeanalizowałem Twój kod i jest bardzo zbliżony do tego co chce osiągnąć - ogólnie prawie wszystko jest OK, jest tylko jeden duuuuży problem, nie wiedzieć czemu funkcja MAX() nie działa jak powinna. Zamiast porównywać całe wydobyte liczby to porównuje tylko pierwszy ich znak. Przykładowo mając: A/7/2012, A/33/2012 i A /252/2012 - jako MAX pokaże 7. Gdy zmienię A/7/2012 na np. A/1/2012 to pokazuje jako MAX liczbę 33 - a powinno we wszystkich przypadkach pokazać 252. Może jakoś trzeba by zdeklarować typ danych bo funkcja nie potrafi rozpoznać że to są liczby?

---------------

Zmieniłem trochę kod, by wyrzucił mi posortowane wyniki i uzyskałem niestety ten sam problem co przy użyciu funkcji MAX(), przykład:

  1. SELECT
  2. LEFT(sub,locate('/',sub)-1) AS Wynik
  3. FROM (
  4. SELECT
  5. substr(Numer,locate('/',Numer)+1,length(Numer)) sub
  6. FROM tabela
  7. ) t ORDER BY Wynik DESC


Wynik:
7
33
152
1
03


A powinno przecież być:
152
33
7

1
03

Zgłupiałem już... ;/
Sephirus
Spróbuj rzucić tą liczbę którą wyciągasz na liczbę - zapoznaj się z CAST

  1. (...) CAST(substr(numer,locate('/',numer)+1,length(numer)) AS UNSIGNED) sub (...)


Może on Ci stringi porównuje po prostu.
poldo
Tak, mam wrażenie że on porównywał stringi - w każdym razie dzięki sazian i Sephirus - udało się w końcu z waszą pomocą ;-)
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.