データベースpet
に次のテーブルmenagerie
があります。
_+--------+-------------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+-------------+---------+------+------------+------------+
| Tommy | Salman Khan | Lebre | NULL | 1999-01-13 | 0000-00-00 |
| Bowser | Diane | dog | m | 1981-08-31 | 1995-07-29 |
+--------+-------------+---------+------+------------+------------+
_
次のクエリを実行すると、次のようになります。
_select owner, curdate() from pet;
_
次の出力が得られます。
_+-------------+------------+
| owner | curdate() |
+-------------+------------+
| Salman Khan | 2016-09-12 |
| Diane | 2016-09-12 |
+-------------+------------+
_
出力には、owner
のすべての値と、各行のcurdate()
から返された値が表示されます。
次のクエリを実行すると、次のようになります。
_select owner, count(*) from pet;
_
次の出力が得られます。
_+-------------+----------+
| owner | count(*) |
+-------------+----------+
| Salman Khan | 2 |
+-------------+----------+
_
私の質問は、curdate()
とcount()
関数の違いは何ですか。これによりMySQL
は2番目のowner
Dianeを出力します。最初の例では?
COUNT()
は、通常_GROUP BY
_句と組み合わされる集計関数です。
curdate()
は、現在の日付を出力する日付関数です。
(私が知る限り)MySQLだけが、_GROUP BY
_句を使用せずにこの構文を許可します。指定しなかったため、COUNT(*)
はテーブル内の行の総数をカウントし、owner
列はランダムに/オプティマイザーのデフォルト/インデックスによって選択されます。
これはあなたの質問でなければなりません:
_select owner, count(*)
from pet
group by owner;
_
これは、オプティマイザーにeach ownerの合計行をカウントするように指示します。
Group by句が言及されていない場合、集計関数はテーブルのデータ全体に適用されます。
EDIT:各行に適用されるカウントは、通常COUNT()
では実行できず、通常は分析関数-> COUNT() OVER(PARTITION...)
で使用されます。 MySQLには存在しません。他のオプションは、この追加の列に_JOIN/CORRELATED QUERY
_を作成することです。
別の編集:各所有者の横にある合計数を知りたい場合は、サブクエリを使用できます。
_SELECT owner,
(SELECT COUNT(*) FROM pet) as cnt
FROM pet
_
これは、このページの下部にあるシナリオとまったく同じように見えます: MySQLドキュメント:4.3.4.8行のカウント 。
ONLY_FULL_GROUP_BYが有効になっていない場合、クエリはすべての行を単一のグループとして扱うことによって処理されますが、名前付き列ごとに選択される値は不確定です。サーバーは、任意の行から値を自由に選択できます。
mysql> SET sql_mode = ''; Query OK, 0 rows affected (0.00 sec) mysql> SELECT owner, COUNT(*) FROM pet; +--------+----------+ | owner | COUNT(*) | +--------+----------+ | Harold | 8 | +--------+----------+ 1 row in set (0.00 sec)
この場合はonly_full_group_by
が設定されていません。
MySQLだけがこの種のクエリを実行できるようにします。
GROUP BY
句では、集計関数と結合されていないすべての列を常に指定する必要があります。そうでない場合、データは1つの行に結合され、集計された列が正しく設定され、他のすべての列がランダムに、またはインデックスで選択されます。
だからあなたはこれが必要です:
SELECT owner, count(*) FROM pet GROUP BY owner;
結果は次のようになります。
Saknan Khan | 1
Diane | 1
これはあなたが達成しようとしていたことですか?
または多分あなたはこれをやろうとしました:
SELECT t.owner,
COUNT(*) as cnt
FROM pet t
CROSS JOIN pet s
GROUP BY t.owner
これにより、各所有者の横に合計数の列が追加されます。
最後のクエリはOracleでは無効です:ORA-00937:単一グループ関数ではありません。これは、GROUPBY句が必要であることを意味します。 MySqlの実装に抜け穴が見つかりました。実稼働システムではこのようなクエリに依存しないでください。MySqlの次のバージョンでは、これが機能しない可能性があります。
ほとんどのDBMSシステムでは、group byのない追加の列を持つcount()のような集計関数は許可されません。理由があります。 DBMSは、グループ化する列を認識していません:-)。
解決策は、次のように、所有者列でクエリをグループ化することです。
SELECT owner, count(*) FROM pet GROUP BY owner;
Count(*)集計関数は、1つの値、つまり合計行数のみを返します。そしてcurdate()関数は、システムの現在の日付を提供するだけです。
はい、これは通常、groupby句を使用せずに発生します。
http://www.w3schools.com/sql/sql_groupby.asp groupby句に関するすべてのリンクを読む必要があります。
すべての列は、集計またはグループ化のいずれかで言及する必要があります