Zliczanie wierszy z podzapytania

14

Proste: chciałbym policzyć liczbę wierszy z zapytania podrzędnego. Pamiętaj, że status określa, czy host jest online, czy nie.

Zły kod

SELECT COUNT(ip_address) FROM `ports` (
    SELECT DISTINCT ip_address FROM `ports` WHERE status IS TRUE
)

Wyjaśnione

Pierwsze zapytanie po uruchomieniu zwraca:

SELECT DISTINCT ip_address FROM `ports` WHERE status IS TRUE
ip_address  
192.168.1.1
192.168.1.2
192.168.1.248
192.168.1.251
192.168.1.254

Drugie uruchomione zapytanie zwraca:

SELECT COUNT(ip_address) FROM `ports`
17

Pytanie

Chciałbym wiedzieć, jak policzyć tę listę 5 adresów IP.

Szukałem w Internecie możliwych rozwiązań tego prostego problemu i po prostu byłem sfrustrowany, więc pomyślałem, że zapytam ekspertów.

polecenie rw
źródło

Odpowiedzi:

18

Aby odpowiedzieć na twoje bezpośrednie pytanie, jak liczyć wiersze podzapytania, składnia jest następująca:

SELECT COUNT(*) FROM (subquery) AS some_name;

Podzapytanie powinno natychmiast następować po słowie kluczowym FROM. (W MySQL obowiązkowe jest również przypisanie nazwy do tego rodzaju podzapytania (tak naprawdę nazywana jest tabelą pochodną ), dlatego można zobaczyć AS some_namenastępujące elementy.) W sposób, w jaki to napisałeś, MySQL interpretuje twój skrypt jako dwa niezależne zapytania, dlatego otrzymujesz dwa zestawy wyników.

Ponieważ w Twoim przypadku jest to podzapytanie

SELECT DISTINCT ip_address FROM `ports` WHERE status IS TRUE

pełne zapytanie wyglądałoby tak:

SELECT COUNT(*) FROM (
    SELECT DISTINCT ip_address FROM `ports` WHERE status IS TRUE
) AS derived;

Ale, jak zasugerował Julien , możesz przepisać zapytanie w następujący sposób:

SELECT COUNT(DISTINCT ip_address) FROM `ports`;

W ten sposób nie potrzebujesz w ogóle tabeli podzapytań / pochodnej, ponieważ funkcja LICZNIK będzie liczyć tylko różne wystąpienia ip_addressw portstabeli.

Andriy M.
źródło
FY: działało również dobrze w Postgres 10: SELECT COUNT(*) FROM (select * from bme_wk_umatch_ug where rdbname = 'xxx) as tocount; musiałem użyć oryginalnej koncepcji OP, ponieważ będę liczył wiersze w podzapytaniu INTERSECT.
JL Peyret
6

Musisz przenieść DISTINCTdo COUNT():

SELECT COUNT(DISTINCT ip_address) FROM `ports`;

Zwraca, 5ponieważ zlicza tylko odrębne wartości, a podzapytanie nie jest już potrzebne.

Jednak to zapytanie zwraca, 17ponieważ w portstabeli jest 17 wierszy :

SELECT COUNT(ip_address) FROM `ports`;

Zobacz ten SQL Fiddle .

Przykładowe dane z 17 wierszami i 5 różnymi adresami IP:

CREATE TABLE ports (ip_address varchar(20));

INSERT INTO `ports`(ip_address) VALUES
  ('192.168.1.1')
  , ('192.168.1.1')
  , ('192.168.1.1')
  , ('192.168.1.2')
  , ('192.168.1.2')
  , ('192.168.1.2')
  , ('192.168.1.2')
  , ('192.168.1.248')
  , ('192.168.1.248')
  , ('192.168.1.248')
  , ('192.168.1.248')
  , ('192.168.1.251')
  , ('192.168.1.251')
  , ('192.168.1.251')
  , ('192.168.1.254')
  , ('192.168.1.254')
  , ('192.168.1.254');
Julien Vavasseur
źródło