Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL]Zapytanie pomijające duplikaty
Forum PHP.pl > Forum > Przedszkole
dopal
Witam,

Założmy, że mam taką tabelę,która nazywa się produkty:

id |owoc |kraj |ilosc
1 banan BRA 2
2 banan KOL 3
3 gruszka POL 5
4 wiśnia RUS 4
5 kiwi AUS 3
6 arbuz POL 2
7 jabłko SLO 5
8 jabłko UKR 4
itd....

Chodzi mi jak powinno wyglądać zapytanie by otrzymać tylko te wyniki, które się nie powtarzają po kolumnie owoc
czyli tylko te:

id |owoc |kraj |ilosc
3 gruszka POL 5
4 wiśnia RUS 4
5 kiwi AUS 3
6 arbuz POL 2

Tylko te owoce, które występują raz w tej tabeli.
Damonsson
  1. GROUP BY owoc
a nie, sorry, źle przeczytałem tongue.gif
dopal
Właśnie nie choddzi o group by, ani o distinct smile.gif
Damonsson
Wiem wiem. Hmmm może coś w stylu
  1. GROUP BY owoc HAVING COUNT(owoc) = 1

Nietestowane.
dopal
Ok, na teście działa, musze teraz to sprawdzić na prawdziwej bazie danych smile.gif
Ale pewnie będzie ok
dzieki.

Niestety na prawdziwej tabeli nie chce to mi zadziałać.

Mam takie zapytanie:
  1. <?php
  2. $query="SELECT * FROM USPOJ
  3. WHERE UPSRPK='E022' AND UPUSDT Between '20120801' And '20120831' AND UPDNNR='12235350' OR
  4. UPSRPK='E022' AND UPUSDT Between '20120801' And '20120831' AND UPDNNR='12055525'
  5. GROUP BY UPDNNR HAVING COUNT(UPDNNR) = 1 ";
  6.  
  7. // jeśli pominę GROUP BY UPDNNR HAVING COUNT(UPDNNR) = 1 to otrzymuję te wyniki co trzeba, ale bez przefilrtowania ( 1 brałem też w cudzysłów )
  8. // czyli zapytanie i pozostała część kodu wykonują sie prawidłowo
  9.  
  10. $result = odbc_exec($connect, $query) or die( odbc_error());
  11.  
  12. $razem=odbc_num_rows($result);
  13.  
  14. $x=0;
  15.  
  16. {
  17.  
  18. while(odbc_fetch_row($result))
  19.  
  20. {
  21. $x++;
  22.  
  23. $a1 = odbc_result($result, 1);
  24. $a2 = odbc_result($result, 2);
  25. $a3 = odbc_result($result, 3);
  26. $a4 = odbc_result($result, 4);
  27. $a5 = odbc_result($result, 5);
  28. $a6 = odbc_result($result, 6);
  29. $a7 = odbc_result($result, 7);
  30. //dalsza część jest chyba bez znaczenia
  31. ?>


Przy takim zapytaniu otrzymuje komunikat:

Warning: odbc_exec() [function.odbc-exec]: SQL error: [IBM][Sterownik ODBC iSeries Access][DB2 UDB]SQL0122 - Niepoprawna kolumna UPPLNR lub wyra�enie na li�cie SELECT., SQL state S1000 in SQLExecDirect in D:\www\apache\htdocs\zest_magpoj.php on line 213
S1000

linia 213 to $result = odbc_exec($connect, $query) or die( odbc_error());

Ma ktoś jakieś rozwiązanie?
alegorn
eh wuja,
skoro korzystasz a Accessa to dlaczego pytasz o mysql.... questionmark.gif?
ja juz nawet nie pamietam czy to jest dostepne w ms access... on ma (miał) ograniczoną implementację sql'a

j.
dopal
Cytat(alegorn @ 13.12.2012, 13:32:55 ) *
eh wuja,
skoro korzystasz a Accessa to dlaczego pytasz o mysql.... questionmark.gif?
ja juz nawet nie pamietam czy to jest dostepne w ms access... on ma (miał) ograniczoną implementację sql'a

j.

A jesteś pewien że to o Accessa chodzi? Bo to jest baza IBM, tak jak w komunikacie.
mmmmmmm
Popraw warunki. Pomieszane ANDy i ORy.
A zapytanie powinno wygladac tak:
  1. $query="SELECT * FROM USPOJ WHERE .... AND UPDNNR IN (SELECT UPDNNR FROM USPOJ
  2. WHERE UPSRPK='E022' AND UPUSDT Between '20120801' And '20120831' AND UPDNNR='12235350' OR
  3. UPSRPK='E022' AND UPUSDT Between '20120801' And '20120831' AND UPDNNR='12055525'
  4. GROUP BY UPDNNR HAVING COUNT(UPDNNR) = 1 )";
dopal
  1.  
  2. $query="SELECT * FROM USPOJ
  3.  
  4. WHERE UPSRPK='E022' AND UPUSDT Between '20120801' And '20120831' AND UPDNNR='12235350' OR
  5. UPSRPK='E022' AND UPUSDT Between '20120801' And '20120831' AND UPDNNR='12055525'
  6. AND UPDNNR IN (SELECT UPDNNR FROM USPOJ
  7. WHERE UPSRPK='E022' AND UPUSDT Between '20120801' And '20120831' AND UPDNNR='12235350' OR
  8. UPSRPK='E022' AND UPUSDT Between '20120801' And '20120831' AND UPDNNR='12055525'
  9. GROUP BY UPDNNR HAVING COUNT(UPDNNR) = 1 )";

Owszem błędu już nie ma, ale wyniki wyświetlają się jak przy takim zapytaniu:
  1. $query="SELECT * FROM USPOJ
  2.  
  3. WHERE UPSRPK='E022' AND UPUSDT Between '20120801' And '20120831' AND UPDNNR='12235350' OR
  4. UPSRPK='E022' AND UPUSDT Between '20120801' And '20120831' AND UPDNNR='12055525'


Otrzymują i w jednym i drugim po 3 wyniki, a po grupowaniu przez UPDNNR itd.
powinienem otrzymać 1 wynik.



Ok, Twoja odpowiedź dała mi pewną wskazówkę.
Zapytanie działa, muszę teraz tylko zwerfikowac poprawność wyników.
alegorn
ok, moja nieuwaga.
bylem pewny ze to nie jest mysql - a Ty tak to opisales.

gdybys napisal to czytelniej - latwiej by bylo odpowiedziec na pytania.

j.

dopal
Mam takie zapytanie, które dobrze mi działa, ale chciałbym je rozbudować.
  1. <?php
  2. $pytanie4="SELECT MAPJP1, COUNT(*) as iloscC FROM MAGPOJ INNER JOIN USPOJ on MADNNR=UPDNNR
  3. WHERE
  4. MAPLIS Like '%{$_POST['kod']}%' AND MAPLIS=UPPLIS AND MASRPK = UPSRPK AND UPSRPK Like '%{$_POST['preparat']}%' AND MADNNR=UPDNNR AND MADNDT Between '".$czas1."' And '".$czas2."' GROUP BY MAPJP1 ORDER BY iloscC DESC";
  5.  


Chciałbym by najpierw grupowanie odbyło się po :
GROUP BY UPDNNR HAVING COUNT(UPDNNR) = 1

a na końcu by było grupowanie
GROUP BY MAPJP1

Zapewne to zapytanie powinno zupełnie inaczej wyglądać, ale może ktoś ma jakąś podpowiedź jak by to było.



Walcze z tym już drugi dzień, może ktoś ma jakieś wskazówki.
Damonsson
  1. SELECT MAPJP1, COUNT(*) AS iloscC FROM MAGPOJ
  2. INNER JOIN USPOJ ON MADNNR=UPDNNR
  3. WHERE MAPLIS LIKE '%{$_POST['kod']}%' AND MAPLIS=UPPLIS AND MASRPK = UPSRPK AND UPSRPK LIKE '%{$_POST['preparat']}%' AND MADNNR=UPDNNR AND MADNDT BETWEEN '".$czas1."' AND '".$czas2."'
  4. GROUP BY MAPJP1, UPDNNR HAVING COUNT(UPDNNR) = 1
  5. ORDER BY iloscC DESC


Tak próbowałeś?
dopal
Nie jest do końca tak jak oczekuję, podobnie robiłem.
Owszem zapytanie zwraca mi prawidłowy wynik, czyli akurat w tym przypadku 9, ale wyświetla wszystkie jako oddzielne rekordy.
A chodzi by po wybraniu UPDNNR HAVING COUNT(UPDNNR) = 1
Wybrał te brekordy, które wystepują raz ( tak jak mi wcześniej mówiłeś )
Następnie chcę by te wyniki wybrane podrupował wg pola MAPJP1, czyli
UPDNNR HAVING COUNT(UPDNNR) = 1 zwraca mi 9 wyników, w tych 9 wynikach w polu MAPJP1 mają np wpisane:
186
198
173
186
198
198
173
180
186

W tym momęcie GROUP BY MAPJP1
powinno pogrupować te 9 rekordów wg tego pola i otrzymać wyniki:
186 - 3 ( jako cyfrę )
198 - 3
173 - 2
180 - 1

Mam nadzieję, że teraz to jest czytelniejsze smile.gif
Masz jakis pomysł?

Dla jasności podam dalszą część kodu, która tyczy się tego zapytania
  1. <?php
  2. $result4 = odbc_exec($connect, $pytanie4) or die( odbc_error());
  3.  
  4. while(odbc_fetch_row($result4))
  5.  
  6. {
  7. $odp3 = odbc_result($result4, 1);
  8. $odp4 = odbc_result($result4, 2);
  9.  
  10. {
  11. echo '<tr>
  12. <td width="30%" align="center">'.$odp3.'</td>
  13. <td width="10%" align="center""><b>'.$odp4.'</b></td>
  14. <td width="10%" align="center">&nbsp;<a href="zest19_wyn.php?more4='.$odp3.' " target=_blank>Szczegóły</a></td>
  15. </tr>';
  16. }}
  17. ?>
mmmmmmm
Zapytanie z zapytania. Podwójne grupowanie.
SELECT ... FROM (SELECT ... FROM ... GROUP ... HAVING ...) x GROUP BY ....
dopal
Cytat(mmmmmmm @ 15.12.2012, 17:13:15 ) *
Zapytanie z zapytania. Podwójne grupowanie.
SELECT ... FROM (SELECT ... FROM ... GROUP ... HAVING ...) x GROUP BY ....

Nie bardzo rozumiem po FROM nie ma podanej tabeli? Co znaczy x?

Coś takiego?

  1.  
  2. $pytanie4="SELECT MAPJP1, COUNT(*) as iloscC FROM (SELECT MAPJP1, COUNT(*) as iloscC FROM MAGPOJ
  3. INNER JOIN USPOJ on MADNNR=UPDNNR
  4. WHERE
  5. MAPLIS Like '%{$_POST['kod']}%' AND MAPLIS=UPPLIS AND MASRPK = UPSRPK AND UPSRPK Like '%{$_POST['preparat']}%' AND MADNNR=UPDNNR AND MADNDT Between '".$czas1."' And '".$czas2."' GROUP BY UPDNNR HAVING COUNT(UPDNNR) = 1 ) MAGPOJ GROUP BY MAPJP1
  6.  
  7. ";
  8.  




Zrobiłem tak i działa.

  1. <?php
  2.  
  3. $pytanie4="SELECT MAPJP1, COUNT(*) as iloscC FROM (SELECT MAPLIS, MASRPK, MAPJP1, MAPJDW, MADNNR, MADNDT, MAPJIL, MAPJWG, MAPJTM, MAPJIJ, MAPJPO, MAISIP, UPPLIS , UPSRPK, UPDNNR, UPUSKD, UPUSDT
  4. FROM MAGPOJ, USPOJ
  5. WHERE MAPLIS Like '%{$_POST['kod']}%' AND MAPLIS=UPPLIS AND MASRPK = UPSRPK AND UPSRPK Like '%{$_POST['preparat']}%' AND MADNNR=UPDNNR AND MADNDT Between '".$czas1."' And '".$czas2."'
  6. AND UPDNNR IN (SELECT UPDNNR FROM USPOJ
  7. WHERE MAPLIS Like '%{$_POST['kod']}%' AND MAPLIS=UPPLIS AND MASRPK = UPSRPK AND UPSRPK Like '%{$_POST['preparat']}%' AND MADNNR=UPDNNR AND MADNDT Between '".$czas1."' And '".$czas2."'
  8. GROUP BY UPDNNR HAVING COUNT(UPDNNR) = 1 ) ) x GROUP BY MAPJP1";
  9.  
  10. ?>


Ewentualnie jeśli, ktoś ma inny pomysł to będę wdzięczny.
mmmmmmm
X to alias do podzapytania. Alias może być do tabeli (FROM tabela1 As X), pola (SELECT bardzodluganazwapola As X), kolumny wyliczanej (SELECT DateDiff(data_od, data_do) As X, podzapytania (jak we wcześniejszym przykładzie) itp.
A nie ma tabeli, bo źródłem danych jest wcześniej wyliczony zbiór rekordów (czyli coś takiego samego jak "wirtualna" tabela)
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.