web-dev-qa-db-ja.com

サブクエリからの行のカウント

シンプル:サブクエリの行数をカウントしたいと思います。 statusは、ホストがオンラインかどうかに注意してください。

悪いコード

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

単独で実行される2番目のクエリはこれを返します。

SELECT COUNT(ip_address) FROM `ports`
17

質問

5つのIPアドレスのリストを数える方法を教えてください。

私はこの単純な問題の可能な解決策をオンラインで見ていて、ただイライラしているので、専門家に尋ねると思いました。

13
rwcommand

差し迫った質問、サブクエリの行をカウントする方法に答えるために、構文は次のとおりです。

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

サブクエリはFROMキーワードの直後に続く必要があります。 (MySQLでは、この種類のサブクエリに名前を割り当てることも必須です(実際には派生テーブルと呼ばれます)。そのため、それに続くAS some_nameを参照してください。)これを書き込んだ方法では、MySQLはスクリプトを2つの独立したクエリとして解釈します。そのため、2つの結果セットを取得しています。

したがって、あなたの場合のサブクエリは

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;

しかし、 ジュリアンが示唆したように 、次のようにクエリを書き直すことができます:

SELECT COUNT(DISTINCT ip_address) FROM `ports`;

この方法では、COUNT関数はportsテーブル内のip_addressの個別の発生のみをカウントするため、サブクエリ/派生テーブルはまったく必要ありません。

18
Andriy M

DISTINCTCOUNT()に移動する必要があります:

SELECT COUNT(DISTINCT ip_address) FROM `ports`;

これは5を返します。これは、個別の値のみをカウントし、サブクエリが不要になったためです。

ただし、portstableには17行あるため、このクエリは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');
6