การนับแถวจากแบบสอบถามย่อย


14

ง่าย: ฉันต้องการนับจำนวนแถวจากแบบสอบถามย่อย โปรดทราบว่าสถานะนั้นไม่ว่าโฮสต์จะออนไลน์หรือไม่

รหัสไม่ถูกต้อง

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

อธิบาย

แบบสอบถามแรกเมื่อรันด้วยตนเองจะส่งคืนสิ่งนี้:

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

เคียวรีที่สองรันด้วยตนเองส่งคืนสิ่งนี้:

SELECT COUNT(ip_address) FROM `ports`
17

คำถาม

ฉันต้องการทราบวิธีนับรายการที่อยู่ IP 5 รายการนั้น

ฉันกำลังค้นหาวิธีแก้ไขปัญหาแบบออนไลน์ที่เป็นไปได้ทางออนไลน์และเพิ่งเริ่มรู้สึกหงุดหงิดดังนั้นฉันจึงถามผู้เชี่ยวชาญ

คำตอบ:


18

ในการตอบคำถามทันทีของคุณวิธีนับแถวของแบบสอบถามย่อยไวยากรณ์จะเป็นดังนี้:

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

แบบสอบถามย่อยควรทำตามคำหลักจากทันที (ใน MySQL มันยังจำเป็นต้องกำหนดชื่อให้กับแบบสอบถามย่อยชนิดนี้ (จริง ๆ แล้วเรียกว่าตารางที่ได้รับ ) ซึ่งเป็นสาเหตุที่คุณสามารถดูได้AS some_nameดังต่อไปนี้) วิธีที่คุณเขียนมัน MySQL ตีความสคริปต์ของคุณเป็น สองข้อความค้นหาอิสระนั่นคือสาเหตุที่คุณได้รับชุดผลลัพธ์สองชุด

ดังนั้นเนื่องจากคำถามย่อยในกรณีของคุณคือ

SELECT DISTINCT ip_address FROM `ports` WHERE status IS TRUE

แบบสอบถามที่สมบูรณ์จะมีลักษณะเช่นนี้:

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

แต่ตามที่ Julien ได้แนะนำคุณสามารถเขียนข้อความค้นหาของคุณใหม่เช่นนี้ได้:

SELECT COUNT(DISTINCT ip_address) FROM `ports`;

วิธีนี้คุณไม่จำเป็นต้องมีแบบสอบถามย่อย / ตารางที่ได้รับเลยเนื่องจากฟังก์ชั่น COUNT จะนับเฉพาะเหตุการณ์ที่เกิดขึ้นip_addressในportsตารางเท่านั้น


FY: ทำงานได้ดีใน Postgres 10 เช่นกัน: SELECT COUNT(*) FROM (select * from bme_wk_umatch_ug where rdbname = 'xxx) as tocount; ฉันต้องใช้แนวคิดดั้งเดิมของ OPs เพราะฉันจะนับจำนวนแถวในแบบสอบถามย่อย INTERSECT
JL Peyret

6

คุณต้องย้ายDISTINCTไปที่COUNT():

SELECT COUNT(DISTINCT ip_address) FROM `ports`;

สิ่งนี้จะส่งคืน5เนื่องจากมันจะนับเฉพาะค่าที่แตกต่างและไม่จำเป็นต้องใช้แบบสอบถามย่อยอีกต่อไป

อย่างไรก็ตามแบบสอบถามนี้ส่งกลับ17เนื่องจากมี 17 แถวในportsตาราง:

SELECT COUNT(ip_address) FROM `ports`;

ดูซอ Fiddleนี้

ข้อมูลตัวอย่างที่มี 17 แถวและ 5 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');
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.