MySQL: COUNT(*) は 1 ??

Twitterに書き殴ったのですが、流れてしまうので、一応こちらにもまとめておこうかと。


 コトの発端はちょっとした打ち間違いだったのですが、MySQL は FROM 書かなくても演算できます。こんな感じ。

mysql> SELECT 3;
+---+
| 3 |
+---+
| 3 |
+---+

mysql> SELECT SQRT(64);
+----------+
| SQRT(64) |
+----------+
|        8 |
+----------+

 ここで、SELECT COUNT(*) とすると何が返ってくるのか。そう、 1 が返ってきます。

mysql> SELECT COUNT(*);
+----------+
| COUNT(*) |
+----------+
|        1 |
+----------+

 EXPLAIN取って、出てきた WARNING を見てみると、どうも COUNT(0) として解釈され、処理が行われている模様。

mysql> EXPLAIN SELECT COUNT(*);
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra          |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
|  1 | SIMPLE      | NULL  | NULL       | NULL | NULL          | NULL | NULL    | NULL | NULL |     NULL | No tables used |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
1 row in set, 1 warning (0.00 sec)

mysql> SHOW WARNINGS;
+-------+------+----------------------------------------------+
| Level | Code | Message                                      |
+-------+------+----------------------------------------------+
| Note  | 1003 | /* select#1 */ select count(0) AS `COUNT(*)` |
+-------+------+----------------------------------------------+
1 row in set (0.00 sec)


じゃぁ、* は、FROMがないときはゼロ相当なのか、というと、そうでもない。

mysql> SELECT *;                                                                                                                 
ERROR 1096 (HY000): No tables used


 カッコ付ければいいってもんでもない。

mysql> SELECT (*);                                                                                                               
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '*)' at line 1

 念のため言っておくけど、no tables だからって、FROM dual をつければいいってもんでもない。

mysql> SELECT * FROM dual;
ERROR 1096 (HY000): No tables used


 と悩んでいるところに、神降臨。



結論。

『dual 表(MySQLでは通常、記述を省略)は、1件を返す』