计数子查询中的行


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

我想知道如何计算5个IP地址的列表。

我一直在网上寻找这个简单问题的可能解决方案,并且感到沮丧,所以我想请专家们。

Answers:


18

为了回答您的直接问题,即如何计算子查询的行,语法如下:

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

子查询应立即跟随FROM关键字。(在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_addressports表中。


风云:在Postgres 10中也能正常工作: SELECT COUNT(*) FROM (select * from bme_wk_umatch_ug where rdbname = 'xxx) as tocount; 我不得不使用OPs的原始概念,因为我要在INTERSECT子查询中计算行数。
JL Peyret

6

你必须移动DISTINCTCOUNT()

SELECT COUNT(DISTINCT ip_address) FROM `ports`;

这将返回,5因为它仅计算不同的值,并且不再需要子查询。

但是,此查询返回,17因为ports表中有17行:

SELECT COUNT(ip_address) FROM `ports`;

请参阅此SQL 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');
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.