Menghitung baris dari subquery

13

Sederhana: Saya ingin menghitung jumlah baris dari sub-kueri. Perhatikan bahwa status adalah apakah tuan rumah sedang online atau tidak.

Kode salah

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

Dijelaskan

Kueri pertama, saat dijalankan dengan sendirinya mengembalikan ini:

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

Permintaan kedua berjalan dengan sendirinya mengembalikan ini:

SELECT COUNT(ip_address) FROM `ports`
17

Pertanyaan

Saya ingin tahu bagaimana cara menghitung daftar 5 alamat IP itu.

Saya telah mencari secara online solusi yang mungkin untuk masalah sederhana ini dan menjadi frustrasi, jadi saya pikir akan bertanya kepada para ahli.

perintah
sumber

Jawaban:

18

Untuk menjawab pertanyaan langsung Anda, bagaimana cara menghitung baris subquery, sintaksnya adalah sebagai berikut:

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

Subquery harus segera mengikuti kata kunci FROM. (Di MySQL juga wajib untuk menetapkan nama ke subquery semacam ini (sebenarnya disebut tabel turunan ), itulah sebabnya Anda dapat melihatnya sebagai AS some_nameberikut.) Cara Anda menulisnya, MySQL mengartikan skrip Anda sebagai dua pertanyaan independen, itu sebabnya Anda mendapatkan dua set hasil.

Jadi, karena subquery dalam kasus Anda adalah

SELECT DISTINCT ip_address FROM `ports` WHERE status IS TRUE

kueri lengkap akan terlihat seperti ini:

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

Tetapi, seperti yang disarankan Julien , Anda dapat menulis ulang kueri Anda seperti ini:

SELECT COUNT(DISTINCT ip_address) FROM `ports`;

Dengan cara ini Anda tidak memerlukan tabel subquery / turunan sama sekali, karena fungsi COUNT hanya akan menghitung kejadian berbeda ip_addressdalam portstabel.

Andriy M
sumber
TA: bekerja dengan baik di Postgres 10 juga: SELECT COUNT(*) FROM (select * from bme_wk_umatch_ug where rdbname = 'xxx) as tocount; Saya harus menggunakan konsep asli OPs karena saya akan menghitung baris dalam subquery INTERSECT.
JL Peyret
6

Anda harus memindahkan DISTINCTke COUNT():

SELECT COUNT(DISTINCT ip_address) FROM `ports`;

Ini mengembalikan 5karena hanya menghitung nilai yang berbeda dan subquery tidak diperlukan lagi.

Namun kueri ini kembali 17karena ada 17 baris dalam portstabel:

SELECT COUNT(ip_address) FROM `ports`;

Lihat SQL Fiddle ini .

Sampel data dengan 17 baris dan 5 IP berbeda:

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
sumber