web-dev-qa-db-ja.com

count()でランダムな行を選択する方法

テーブル名:

g_number  name
123       John
123       Sara
123       Michael

1つのクエリで同じg_numberを持つ1つのランダムな名前とすべての名前の数量を取得したい:

SELECT name, count(*) cnt
FROM names
WHERE g_number='123'
ORDER BY Rand()

しかし、結果は常に同じです

name    cnt
John    3

Count()はORDER BY Rand()行を無視するように見えます。それが問題です。1つのクエリでこれを解決することは可能ですか?

1
Igor

1つのクエリで2つの異なることを実行したいと思います。

  1. ランダムに1つ選択しますnameすべての中から1つ `WHERE g_number = 123
  2. 行をカウントall行_WHERE g_number=123_。

それがあなたがやりたいことなら、twoサブクエリでそれを行います:

_SELECT
   (
     SELECT name
     FROM t
     WHERE g_number = 123
     ORDER BY Rand()
     LIMIT 1
   ) AS name
   , (
     SELECT count(*)
     FROM t
     WHERE g_number = 123
   ) AS count_of_123
_

結果は次のようになります。

_|    name | count_of_123 |
|---------|--------------|
|    Sara |            3 |
_

または

_|    name | count_of_123 |
|---------|--------------|
| Michael |            3 |
_

または

_|    name | count_of_123 |
|---------|--------------|
|    John |            3 |
_

http://sqlfiddle.com/#!9/5342d2/8/ で確認できます。

これはMySQLだけではなく、標準SQLです(Rand()関数の名前を除いて、DBMSに依存している可能性があります)。クエリは、2つの(関連するが異なる)ことを実行するという事実も明確に反映しています。 SQLFiddleで PostgreSQLバージョンSQLite を確認することもできます。


MySQLのレルム内では、同様に機能する非標準のクエリを1つ使用できます(パフォーマンスに関してはおそらく優れています)。

_SELECT
   name, count(*) AS count_of_123
FROM
   (
     SELECT name
     FROM t
     WHERE g_number = 123
     ORDER BY Rand()
   ) AS q0 ;
_

これは元のポスターが考えていたものに近いと思います。それでも、私はそれに頼らない。これは標準SQLから非常に遠いです。 MySQLmightは、これの実装方法と将来の動作を変更することを決定します。また、私見では、クエリの目的があまり明確ではないです。

http://sqlfiddle.com/#!9/5342d2/10/ で確認してください

2
joanolo

別の方法...

SELECT  SUBSTRING_INDEX(GROUP_CONCAT(name ORDER BY Rand()),
                       ',', 1)  AS random_name,
        COUNT(*) AS ct
    FROM names
    WHERE g_number='123';

nameにコンマがないと想定しています。)

1
Rick James