Zastanawiam się, jak napisać to zapytanie.
Wiem, że ta faktyczna składnia jest nieprawdziwa, ale pomoże ci zrozumieć, czego chcę. Potrzebuję go w tym formacie, ponieważ jest on częścią znacznie większego zapytania.
SELECT distributor_id,
COUNT(*) AS TOTAL,
COUNT(*) WHERE level = 'exec',
COUNT(*) WHERE level = 'personal'
Potrzebuję tego wszystkiego w jednym zapytaniu.
Ponadto musi znajdować się w jednym wierszu, więc następujące elementy nie będą działać:
'SELECT distributor_id, COUNT(*)
GROUP BY distributor_id'
SELECT distributor_id, COUNT(*) AS TOTAL, COUNT(*) WHERE level = 'exec', COUNT(*) WHERE level = 'personal'
Odpowiedzi:
Możesz użyć
CASE
instrukcji z funkcją agregującą. Jest to w zasadzie to samo, coPIVOT
funkcja w niektórych RDBMS:źródło
COUNT
będzie liczyćdistributor_id
mądrze. nie wszystkie rzędy tabeli, prawda?Jeden sposób, który na pewno działa
EDYCJA:
Zobacz rozkład wydajności @ KevinBalmforth, aby dowiedzieć się, dlaczego prawdopodobnie nie chcesz używać tej metody, a zamiast tego powinieneś wybrać odpowiedź @ Taryn ♦. Zostawiam to, aby ludzie mogli zrozumieć ich opcje.
źródło
sum(case...)
należy rozważyć rozwiązanie.group by
z korzyścią zastąpienia całego zagnieżdżonego zapytania prostymcount(*)
jak pokazuje @Mihai - z dalszymi uproszczeniami składni tylko w MySQL.COUNT
liczy tylkonon null
wartości, aDECODE
zwróci wartość inną niż null1
tylko wtedy, gdy warunek jest spełniony.źródło
distributor_id
pokaże zapytanie? Pokazuje w sumie 1 wiersz.Opierając się na innych opublikowanych odpowiedziach.
Oba z nich wygenerują prawidłowe wartości:
Jednak wydajność jest zupełnie inna, co oczywiście będzie bardziej odpowiednie w miarę wzrostu ilości danych.
Odkryłem, że przy założeniu braku indeksów w tabeli, zapytanie wykorzystujące SUMy wykonałoby skanowanie pojedynczej tabeli, podczas gdy zapytanie z LICZNIKAMI wykonałoby wiele skanów tabeli.
Na przykład uruchom następujący skrypt:
Podświetl 2 instrukcje SELECT i kliknij ikonę Wyświetl szacowany plan wykonania. Zobaczysz, że pierwsza instrukcja wykona jedno skanowanie tabeli, a druga zrobi 4. Oczywiście jedno skanowanie tabeli jest lepsze niż 4.
Interesujące jest także dodanie indeksu klastrowego. Na przykład
Pierwszy WYBÓR powyżej wykona pojedyncze skanowanie indeksu klastrowanego. Drugi WYBÓR wykona 4 Wyszukiwanie indeksów klastrowych, ale są one nadal droższe niż pojedyncze skanowanie indeksów klastrowych. Próbowałem tego samego na stole z 8 milionami wierszy, a drugi SELECT był wciąż znacznie droższy.
źródło
W przypadku MySQL można to skrócić do:
źródło
Cóż, jeśli musisz mieć to wszystko w jednym zapytaniu, możesz utworzyć połączenie:
Lub, jeśli możesz to zrobić po przetworzeniu:
Otrzymasz obliczenia dla każdego poziomu i musisz zsumować je wszystkie, aby uzyskać sumę.
źródło
UNION
że jest bardzo pomocny podczas generowania raportu zawierającego wiele instancjiCOUNT(*)
funkcji.#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ') FROM distributors UNION SELECT COUNT() AS EXEC_COUNT FROM distributors WHERE ' at line 1
.Robię coś takiego, w którym po prostu nadaję każdej tabeli nazwę ciągu, aby zidentyfikować ją w kolumnie A, i liczbę kolumn. Następnie łączę je wszystkie, aby się ułożyły. Moim zdaniem wynik jest dość - nie jestem pewien, jak skuteczny jest w porównaniu z innymi opcjami, ale dostałem to, czego potrzebowałem.
Wynik:
źródło
a query that I created makes ...
- gdzie jest to zapytanie?Na podstawie zaakceptowanej odpowiedzi Bluefeet z dodatkowym niuansem przy użyciu
OVER()
:Używanie
OVER()
z niczym w () da ci całkowitą liczbę dla całego zestawu danych.źródło
Myślę, że to też może dla ciebie zadziałać
select count(*) as anc,(select count(*) from Patient where sex='F')as patientF,(select count(*) from Patient where sex='M') as patientM from anc
a także możesz wybierać i liczyć podobne tabele
select count(*) as anc,(select count(*) from Patient where Patient.Id=anc.PatientId)as patientF,(select count(*) from Patient where sex='M') as patientM from anc
źródło