Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> JOIN po raz kolejny
KR2615
post
Post #1





Grupa: Zarejestrowani
Postów: 311
Pomógł: 13
Dołączył: 7.05.2007

Ostrzeżenie: (0%)
-----


Witam
Proszę o pomoc w zsformułowaniu zapytania. Mam baze danych z ludkami o strukturze id, name, id_miasta. Druga tabela z przypisanymi do nich taryfami o strukturze id, id_klienta, id_taryfy. Jakie zapytanie klepnac, zeby zliczylo mi ile klientow jest w kazdej taryfie (GROUP BY `id_taryfy`) z miasta o id 6? I drugi problem, jak wydobyc z bazy klientow, do ktorych nie jest przypisana zadna taryfa? Z gory dzieki za pomoc!


--------------------
Go to the top of the page
+Quote Post
sowiq
post
Post #2





Grupa: Zarejestrowani
Postów: 1 890
Pomógł: 339
Dołączył: 14.12.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Ilość klientów:
  1. SELECT t.id_taryfy, COUNT(1)
  2. FROM tabela_z_klientami k
  3. JOIN tabela_z_taryfami t ON (k.id = t.id_klienta)
  4. GROUP BY t.id_taryfy;


Puste taryfy:
  1. SELECT *
  2. FROM tabela_z_klientami k
  3. WHERE NOT EXIST(
  4. SELECT 1 FROM tabela_z_taryfami t WHERE t.id_klienta = k.id
  5. )


albo (musisz sprawdzić które będzie szybsze, bo nie jestem pewien):
  1. SELECT *
  2. FROM tabela_z_klientami
  3. WHERE id NOT IN(
  4. SELECT id_klienta FROM tabela_z_taryfami
  5. )

Go to the top of the page
+Quote Post
mmmmmmm
post
Post #3





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

Ostrzeżenie: (0%)
-----


  1. SELECT t.id_taryfy, COUNT(k.id)
  2. FROM tabela_z_klientami k
  3. JOIN tabela_z_taryfami t ON (k.id = t.id_klienta)
  4. GROUP BY t.id_taryfy;

Nie powinno się stosowac (sorry, uczyc) z COUNT(1). De facto jest to poprawne, ale tylko dla JOIN, dla innych juz niekoniecznie.
A co do drugiego, to myslee ze najszybsze bedzie:
  1. SELECT k.*
  2. FROM tabela_z_klientami k
  3. LEFT JOIN tabela_z_taryfami t ON (k.id = t.id_klienta)
  4. WHERE t.id_klienta IS NULL;
Go to the top of the page
+Quote Post
sowiq
post
Post #4





Grupa: Zarejestrowani
Postów: 1 890
Pomógł: 339
Dołączył: 14.12.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Cytat(mmmmmmm @ 18.12.2013, 11:39:39 ) *
Nie powinno się stosowac (sorry, uczyc) z COUNT(1). De facto jest to poprawne, ale tylko dla JOIN, dla innych juz niekoniecznie.


Chyba nie do końca tak jest. Wychodzi na to, że COUNT(*) i COUNT(1) są równoważne jeśli nie używasz MyISAM.

Wszystkie poniższe rozwiązania działają identycznie (a przynajmniej jeśli wierzyć odpowiedzi ze StackOverflow) - http://stackoverflow.com/questions/5179969...ount-or-count1:
Kod
COUNT(*)
COUNT(1)
COUNT(pk-column)
COUNT(any-non-nullable-column)
Go to the top of the page
+Quote Post
mmmmmmm
post
Post #5





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

Ostrzeżenie: (0%)
-----


  1. SELECT kategoria, count(1), count(*), COUNT(sub2.id_kategorii) FROM
  2. (
  3. SELECT 1 id_kategorii, 'pierwsza' kategoria
  4. UNION ALL
  5. SELECT 2, 'druga'
  6. ) sub
  7. JOIN
  8. (
  9. SELECT 1 id_kategorii, 1 id_klienta
  10. UNION ALL
  11. SELECT 1 id_kategorii, 2 id_klienta
  12. ) sub2 ON sub.id_kategorii=sub2.id_kategorii
  13. GROUP BY 1

Sprawdz.
A potem zamień JOIN na LEFT JOIN.
Go to the top of the page
+Quote Post
sowiq
post
Post #6





Grupa: Zarejestrowani
Postów: 1 890
Pomógł: 339
Dołączył: 14.12.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Tylko nie wiem co ten przykład ma udowodnić? W obu przypadkach COUNT(1) zwraca to samo co COUNT(*). Przynajmniej u mnie, na MySQL 5.5.32.

Kod
mysql> SELECT kategoria, count(1), count(*), COUNT(sub2.id_kategorii)
    -> FROM
    ->     ( SELECT 1 id_kategorii, 'pierwsza' kategoria UNION ALL SELECT 2, 'druga' ) sub
    -> LEFT JOIN
    ->     (SELECT 1 id_kategorii, 1 id_klienta UNION ALL SELECT 1 id_kategorii, 2 id_klienta ) sub2
    -> ON sub.id_kategorii=sub2.id_kategorii
    -> GROUP BY 1\G
*************************** 1. row ***************************
               kategoria: druga
                count(1): 1
                count(*): 1
COUNT(sub2.id_kategorii): 0
*************************** 2. row ***************************
               kategoria: pierwsza
                count(1): 2
                count(*): 2
COUNT(sub2.id_kategorii): 2
2 rows in set (0.00 sec)

mysql> SELECT kategoria, count(1), count(*), COUNT(sub2.id_kategorii)
    -> FROM
    ->     ( SELECT 1 id_kategorii, 'pierwsza' kategoria UNION ALL SELECT 2, 'druga' ) sub
    -> JOIN
    ->     (SELECT 1 id_kategorii, 1 id_klienta UNION ALL SELECT 1 id_kategorii, 2 id_klienta ) sub2
    -> ON sub.id_kategorii=sub2.id_kategorii
    -> GROUP BY 1\G
*************************** 1. row ***************************
               kategoria: pierwsza
                count(1): 2
                count(*): 2
COUNT(sub2.id_kategorii): 2
1 row in set (0.00 sec)
Go to the top of the page
+Quote Post
mmmmmmm
post
Post #7





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

Ostrzeżenie: (0%)
-----


Ale co innego niż Count(sub2.id_kategorii).
I o to chodzi. Bo ten ostatni jest prawidłowy.
Go to the top of the page
+Quote Post
sowiq
post
Post #8





Grupa: Zarejestrowani
Postów: 1 890
Pomógł: 339
Dołączył: 14.12.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Ale to są dwie, zupełnie różne rzeczy. COUNT(1) i COUNT(*) zwracają to samo, są jakby aliasami do tego samego. Jak dasz COUNT(jakas_kolumna), to dostaniesz liczbę rekordów, w których ta kolumna nie jest NULL-em.

Czyli wszystko się zgadza z Twoim przykładem i z tym, co napisałem wcześniej. I szczerze mówiąc trochę nie wiem już o co Ci chodzi.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 19.08.2025 - 07:27