Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: mulące zapytanie... Jak to rozwiązać
Forum PHP.pl > Forum > Bazy danych > MySQL
miccom
Witam.
Mam takie oto bazy.

  1. -- phpMyAdmin SQL Dump
  2. -- version 3.3.10
  3. -- <a href="http://www.phpmyadmin.net" target="_blank">http://www.phpmyadmin.net</a>
  4. --
  5. -- Host: localhost
  6. -- Czas wygenerowania: 12 Kwi 2013, 11:55
  7. -- Wersja serwera: 5.1.56
  8. -- Wersja PHP: 5.3.6
  9.  
  10. SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
  11.  
  12.  
  13. /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
  14. /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
  15. /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
  16. /*!40101 SET NAMES utf8 */;
  17.  
  18. -- --------------------------------------------------------
  19.  
  20. --
  21. -- Struktura tabeli dla `danejednostek`
  22. --
  23.  
  24. CREATE TABLE IF NOT EXISTS `danejednostek` (
  25. `idDaneJednostek` int(11) NOT NULL AUTO_INCREMENT,
  26. `idGracza` int(11) NOT NULL,
  27. `user` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  28. `idJednostki` int(11) NOT NULL COMMENT '1: piechota; 2: lotnictwo; 3: pancerne; 4: przeciwlotnicze; 5: flota; 6: artyleria;',
  29. `nazwaJednostki` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  30. `nacjaJednostki` int(11) NOT NULL COMMENT '1:polak, 2:niemiec',
  31. `mapa` int(11) NOT NULL,
  32. PRIMARY KEY (`idDaneJednostek`)
  33. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=2820 ;
  34.  
  35. --
  36. -- Zrzut danych tabeli `danejednostek`
  37. --
  38.  
  39. INSERT INTO `danejednostek` (`idDaneJednostek`, `idGracza`, `user`, `idJednostki`, `nazwaJednostki`, `nacjaJednostki`, `mapa`) VALUES
  40. (1430, 1, 'system1', 4, '37mm FlaKzwilling 43 L / 89', 2, 4),
  41. (2, 2, 'system2', 6, '105mm M2A1 L / 22.5', 1, 5),
  42. (3, 3, 'system3', 4, 'Flakpanzer IV Wirbelwind', 2, 4),
  43. (4, 4, 'system4', 1, 'Oddział ciężkiej piechoty', 1, 5),
  44. (5, 5, 'system5', 2, 'MiG-3', 1, 7);


  1. -- phpMyAdmin SQL Dump
  2. -- version 3.3.10
  3. -- <a href="http://www.phpmyadmin.net" target="_blank">http://www.phpmyadmin.net</a>
  4. --
  5. -- Host: localhost
  6. -- Czas wygenerowania: 12 Kwi 2013, 12:02
  7. -- Wersja serwera: 5.1.56
  8. -- Wersja PHP: 5.3.6
  9.  
  10. SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
  11.  
  12.  
  13. /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
  14. /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
  15. /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
  16. /*!40101 SET NAMES utf8 */;
  17.  
  18. -- --------------------------------------------------------
  19.  
  20. --
  21. -- Struktura tabeli dla `miasta`
  22. --
  23.  
  24. CREATE TABLE IF NOT EXISTS `miasta` (
  25. `idGracza` int(11) NOT NULL,
  26. `mapa` int(11) NOT NULL,
  27. `nrHexa` int(11) NOT NULL,
  28. `nacja` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  29. `urlop` datetime NOT NULL,
  30. `ochrona` datetime NOT NULL,
  31. `poz_obrony` int(11) NOT NULL,
  32. `nazwa` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  33. `id_miasta` int(11) NOT NULL AUTO_INCREMENT,
  34. PRIMARY KEY (`id_miasta`),
  35. KEY `mapa` (`mapa`,`nacja`),
  36. KEY `nrHexa` (`nrHexa`,`nacja`),
  37. KEY `mapa_2` (`mapa`,`nrHexa`)
  38. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=34 ;
  39.  
  40. --
  41. -- Zrzut danych tabeli `miasta`
  42. --
  43.  
  44. INSERT INTO `miasta` (`idGracza`, `mapa`, `nrHexa`, `nacja`, `urlop`, `ochrona`, `poz_obrony`, `nazwa`, `id_miasta`) VALUES
  45. (0, 62, 6017, '2', '0000-00-00 00:00:00', '0000-00-00 00:00:00', 100, 'BERLIN', 1),
  46. (22, 124, 2308, '2', '0000-00-00 00:00:00', '2013-02-24 23:56:48', 100, 'miccom1', 2),
  47. (12, 143, 13903, '1', '0000-00-00 00:00:00', '2013-02-17 17:53:04', 100, 'miccom2', 3),
  48. (5, 61, 6601, '2', '0000-00-00 00:00:00', '2013-03-27 15:23:28', 100, 'miccom3', 23),
  49. (38, 142, 13895, '1', '0000-00-00 00:00:00', '2013-02-18 10:37:19', 100, 'miccom4', 5),
  50. (0, 0, 0, NULL, '0000-00-00 00:00:00', '0000-00-00 00:00:00', 100, 'WARSZAWA', 22);
  51.  



I do tego zapytanie:
  1. SELECT *
  2. FROM danejednostek
  3. WHERE mapa
  4. IN (
  5. SELECT mapa
  6. FROM danejednostek
  7. WHERE nacjaJednostki ='. $Session->gracz['nacja'].' UNION SELECT mapa FROM miasta WHERE nacja='.$Session->gracz['nacja'].'
  8. )';


I przy 2500 rekordów to zapytanie trwa 1700ms... Aż boję się, jak będę miał kilkanaście tysięcy bo tak mam, nawet do 20 tysięcy rekordów...

Czy da się jakoś to optymalnie "zapytać"?
Proszę o pomoc, oczywiście płatną jeśli zajdzie taka potrzeba smile.gif
nospor
yy..... ale po co ci tam podzapytanie i to z UNION na dodatek? Nie umiesz zwykłego OR w warunku dac?
miccom
Niestety, zapytanie:
  1. SELECT *
  2. FROM danejednostek
  3. WHERE mapa
  4. IN (
  5. SELECT mapa
  6. FROM danejednostek
  7. WHERE nacjaJednostki ='. $Session->gracz['nacja'].' [b]OR[/b] mapa FROM miasta WHERE nacja='.$Session->gracz['nacja'].'
  8. )';

nie działa ;/
matiit
No tak, miałem przed chwilą ten sam problem smile.gif
W postgresql to działa jak coś;P
miccom
Heh, ale jak to zrobić w mysql...
Bo nie wiem czy dam radę teraz przesiąść się na inną bazę danych;/
nospor
OR[/b] mapa FROM miasta WHERE nacja='.$Session->gracz['nacja'].'
.... co to jest?

Zajrzyj do manuala do składni SELECT i zobacz jak sie robi OR w where....

I poraz kolejny sie pytam: po co ci to podzapytanie?? Ono jest zbędne.... WHERE i OR ma byc w głównym zapytaniu...



edit: sorka, nie dolukalem, że ty latasz po różnych tabelach.
W takim wypadku łączysz tabele przez LEFT JOIN i nadal ma być bez podzapytania smile.gif
miccom
nospor, ale jak wyciągnąć numery mapek z tabeli danejendostek i miasta aby wyciągnąć wszystkie jednostki które znajdują sie na tych mapkach?
nospor
No przecież mówie: left join

SELECT *
FROM danejednostek
left join miasta on (miasta.nacja='.$Session->gracz['nacja'].' and danejednostek.mapa=miasta.mapa)
WHERE danejednostek.nacjaJednostki ='. $Session->gracz['nacja'].' or miasta.mapa is not null
miccom
dałem takie zapytanie...
  1. $statement='SELECT *
  2. FROM danejednostek
  3. left join miasta on (miasta.nacja=2 and danejednostek.mapa=miasta.mapa)
  4. WHERE danejednostek.idGracza!=0 AND danejednostek.urlop =0 AND (danejednostek.zanurzenie=0 OR (danejednostek.zanurzenie=1 AND danejednostek.idGracza=1 ) ) AND danejednostek.nacjaJednostki =2 or miasta.mapa is not null';
  5.  
  6. $result = mysql_query($statement);
  7. //$dane_jednostek = array();
  8. $liczba_wierszy = mysql_num_rows($result);
  9. while($wyniki=mysql_fetch_array($result)){
  10. echo "jednostka nr =".$wyniki['idDaneJednostek'].", odgracza=".$wyniki['idGracza']."<br>";
  11. }

i otrzymałem coś takiego...

  1. jednostka nr =3, id_gracza=20
  2. jednostka nr =3, id_gracza=39
  3. jednostka nr =12, id_gracza=
  4. jednostka nr =13, id_gracza=20
  5. jednostka nr =13, id_gracza=39
  6. jednostka nr =15, id_gracza=
  7. jednostka nr =790, id_gracza=5
  8. jednostka nr =37, id_gracza=20
  9. jednostka nr =37, id_gracza=39
  10. jednostka nr =38, id_gracza=30
  11. jednostka nr =38, id_gracza=42
  12. jednostka nr =44, id_gracza=20
  13. jednostka nr =44, id_gracza=39
  14. jednostka nr =50, id_gracza=5
  15. jednostka nr =52, id_gracza=
  16. jednostka nr =58, id_gracza=
  17. jednostka nr =60, id_gracza=20
  18. jednostka nr =60, id_gracza=39
  19. jednostka nr =63, id_gracza=20
  20. jednostka nr =63, id_gracza=39
  21. jednostka nr =64, id_gracza=20
  22. jednostka nr =64, id_gracza=39
  23. jednostka nr =1428, id_gracza=1
  24. jednostka nr =70, id_gracza=20
  25. jednostka nr =70, id_gracza=39
  26. jednostka nr =85, id_gracza=
  27. jednostka nr =86, id_gracza=22
  28. jednostka nr =87, id_gracza=20


Dlaczego dla niektórych jednostek nie pokazuje mi id_gracza?
Sprawdzałem, id tych graczy jest w bazie danych.
nospor
1) Albo tabela miasta ma pole idGracza i akurat ci nadpisuje to id z głównej tabeli
2) Albo poprostu nie masz w bazie tego ustawionego

Innych możliwości nie ma
miccom
No tak, mam ta tabela idGracza, ale jak to wykluczyć z wyników zapytania?
nospor
Masz niezły burdel w tych tabelach....

Co do problemu: to pobieraj tylko z tabeli danejjednostek, bo tylko to ciebie interesuje przeciez

$statement='SELECT danejednostek.* FROM danejednostek
miccom
I tak smile.gif
Zapytanie:
  1. $statement ='SELECT danejednostek.*
  2. FROM danejednostek
  3. left join miasta on (miasta.nacja='.$Session->gracz['nacja'].' and danejednostek.mapa=miasta.mapa)
  4. WHERE danejednostek.idGracza!=0 AND danejednostek.urlop =0 AND danejednostek.zanurzenie=0 AND danejednostek.nacjaJednostki ='. $Session->gracz['nacja'].' or miasta.mapa is not null';


nie respektuje mi warunku danejednostek.zanurzenie=0 ani danejednostek.urlop =0
Czyli wyciąga mi dane nawet te, których nie chcę wyciągać smile.gif
Dlaczego po WHERE nic nie respektuje?
Gdzie mam wstawić warunki do ograniczenia danych wyciąganych z mysql?

Łopatologicznie myśląc zapytanie wyciąga jednostki: gdzie nacja jest równa nacji gracza i mapa jednostki jest równa mapie miasta...
A ja chcę wyciągnąć wszystkie jednostki z mapek, na których stoi ( przynajmniej jedna jednostka tej samej nacji co gracza LUB jakiekolwiek miasto tej samej nacji co gracza ).


mmmmmmm
  1. $statement ='SELECT danejednostek.*
  2. FROM danejednostek
  3. left join miasta on (miasta.nacja='.$Session->gracz['nacja'].' and danejednostek.mapa=miasta.mapa)
  4. WHERE (danejednostek.idGracza!=0 AND danejednostek.urlop =0 AND danejednostek.zanurzenie=0 AND danejednostek.nacjaJednostki ='. $Session->gracz['nacja'].') or miasta.mapa is not null';
miccom
To nie to... nadal wyciąga dane z zanurzenie=1...a nie powinno

Podbijam post gdyż chciałbym poznać rozwiązanie smile.gif
Jak wyciągnąć dane z jednej tabeli biorąc pod uwagę dane z tej jednej i z drugiej jako warunki...
nospor, zajrzyj tu jeszcze raz:) please smile.gif
Już jestem/jesteś tak blisko!
nospor
Cytat
nie respektuje mi warunku danejednostek.zanurzenie=0 ani danejednostek.urlop =0

Ponieważ masz OR
... or miasta.mapa is not null
ten or powoduje anulowanie tamtych warunków w AND.

Jak chcesz by były i one brane pod uwagę to dołóż je do OR
... or miasta.mapa is not null and danejednostek.urlop =0 AND danejednostek.zanurzenie=0

Ot i cała filozofia - prosta logika
miccom
No nadal nie to...
Wrzucam zapytanie:
  1. SELECT danejednostek. *
  2. FROM danejednostek
  3. LEFT JOIN miasta ON ( miasta.nacja =2
  4. AND danejednostek.mapa = miasta.mapa )
  5. WHERE danejednostek.nacjaJednostki =2
  6. OR miasta.mapa IS NOT NULL
  7. AND danejednostek.idGracza !=0
  8. AND danejednostek.urlop =0
  9. AND danejednostek.zanurzenie =0

i nadal wyciąga mi dane z nacjaJednostki=1 i nacjaJednostki=2, z zanurzenie=1 itp...
Powoli rezygnuję...
Wyciąga wszystkie dane...

nospor, ja myślę nad tym zapytaniem już długi czas...
Może tobie wydaje się że ja idę na łatwiznę... ale tak nie jest...
Gdzie mam szukać pomocy?
nospor
No nie wytrzyma....

Ja ci kazałem dodać coś do OR, tak? Tak.
Czy ja ci w którymś miejscu kazałem usuwać z innego miejsca coś? Nie! Czytaj proszę to co ci piszą. Jak ci mowią: dodac cos tu, to znaczy dodać coś tu a nie dodaj coś tu a zabierz stamtąd...
miccom
No niestety...
moje zapytanie to:
  1. SELECT danejednostek . *
  2. FROM danejednostek
  3. LEFT JOIN miasta ON ( miasta.nacja=2
  4. AND danejednostek.mapa = miasta.mapa )
  5. WHERE (
  6. danejednostek.idGracza!=0
  7. AND danejednostek.urlop=0
  8. AND danejednostek.zanurzenie=0
  9. AND danejednostek.nacjaJednostki=2
  10. )
  11. OR miasta.mapa IS NOT NULL
  12. AND danejednostek.idGracza!=0
  13. AND danejednostek.urlop=0
  14. AND danejednostek.zanurzenie=0


Zapytanie nie działa... wyciąga mi wszystkie, nawet te których ma nie wyciągać...
Szkoda że tak trudno wpisać całe zapytanie...
Szkoda że tak trudno sprawdzić u Was na localu czy to co podajecie działa...

Powyższe zapytanie wyciąga dane wszystkich jednostek... zresztą...ja to już pisałem.
Dziękuję za bezowocną pomoc sad.gif



nospor
spróbuj jeszcze nie:
OR miasta.mapa IS NOT NULL

AND danejednostek.idGracza!=0

AND danejednostek.urlop=0

AND danejednostek.zanurzenie=0
a
OR (miasta.mapa IS NOT NULL

AND danejednostek.idGracza!=0

AND danejednostek.urlop=0

AND danejednostek.zanurzenie=0)

Ale to nie powinno mieć znaczenia.
To zapytanie nie ma prawa pobierać ci wszystkiego, bo jasno i czytelnie określają to warunki

Spróbuj jeszcze tak
  1. SELECT danejednostek . *
  2. FROM danejednostek
  3. LEFT JOIN miasta ON ( miasta.nacja=2
  4. AND danejednostek.mapa = miasta.mapa
  5. AND danejednostek.idGracza!=0
  6. AND danejednostek.urlop=0
  7. AND danejednostek.zanurzenie=0
  8. )
  9. WHERE (
  10. danejednostek.idGracza!=0
  11. AND danejednostek.urlop=0
  12. AND danejednostek.zanurzenie=0
  13. AND danejednostek.nacjaJednostki=2
  14. )
  15.  
  16. OR miasta.mapa IS NOT NULL

Jeśli i to będzie ci zwracać zanurzenie =1 to albo ja jestem ślepy, albo ty coś kręcisz smile.gif

miccom
OK, nie ważne...
Poddaję się... nie wyciąga mi danych z zanurzenie=0, ale wyciąga mi jednostki wrogów z mapek, na których nie ma żadnej jednostki sojuszniczej więc nie powinienem ich widzieć... tak samo nie wyciąga mi jednostek wroga, na których mam jednostkę sojuszniczą... a te z kolei trzeba pokazać...
Dobra... olać to, dam zlecenie na oferię bo widzę że to gruba sprawa i wychodzi na to, że na tym forum nie znajdę pomocy sad.gif
Pozdrawiam.
miccom
nospor
Cytat
że na tym forum nie znajdę pomocy
Przestan walić jakieś smuty i wygadywać głupoty że pomocy na forum nie dostajesz... że niby co przez tyle postów tutaj robię? Nie udzielam ci pomocy?

Dostałeś poprawne zapytanie które powinno działać. Jeśli ci nie działa to coś poprostu kręcisz, ale nie mogę tego sprawdzić bo nie mam przed sobą twojej bazy. Wersja bazy, którą podałeś w pierwszym poscie jest nieaktualna w porównaniu z zapytaniami które tu podajesz - brakuje kilku pól, a co za tym idzie i dane są nie takie.
miccom
Witam.
Dla potomnych!
Kosztowało mnie to 20pln smile.gif
Mówiłem z enie chcę za darmo.
Zapytanie które realizuje to co chcę to:
  1. SELECT
  2. *
  3. FROM
  4. (SELECT
  5. *
  6. FROM
  7. danejednostek
  8. WHERE
  9. urlop = 0 AND (zanurzenie = 0 OR (zanurzenie = 1 AND idGracza =
  10. 1))) jednostki
  11. JOIN
  12. (SELECT
  13. mapa AS limit_mapa
  14. FROM
  15. danejednostek
  16. WHERE
  17. nacjaJednostki = 2 UNION SELECT
  18. mapa
  19. FROM
  20. miasta
  21. WHERE
  22. nacja = 2
  23. GROUP BY mapa) mapy ON mapy.limit_mapa = jednostki.mapa


Z wcześniejszego zapytania i generowania ok. 1,4sek... nowe zapytanie realizuje się w 0,007s:)
W każdym razie dziękuję za pomoc.
Pozdrawiam.
miccom

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.