30. 肩慣らし
何のエラーが出る︖
SEECT -- Invalid Syntax
nonexistent_column_in_select_list
FROM
nonexistent_table
WHERE
nonexistent_column_in_where_clause = '..'
ORDER BY
nonexistent_column_in_orderby_clause;
29/105
31. 答え
MySQL error code 1064 (ER̲PARSE̲ERROR): %s near
ʻ%-.80sʼ at line %d
ERROR 1064 (42000): You have an error in your SQL syntax; check
the manual that corresponds to your MySQL server version for th
e right syntax to use near '..'
30/105
48. こんな結果セットがあった時に
mysql80 5> WITH RECURSIVE june AS (
-> SELECT CAST('2017/06/01' AS DATE) AS dt
-> UNION ALL
-> SELECT DATE_ADD(dt, INTERVAL 1 DAY) AS dt FROM june WHER
E dt < '2017/06/30')
-> SELECT * FROM june;
+------------+
| dt |
+------------+
| 2017-06-01 |
| 2017-06-02 |
| 2017-06-03 |
..
| 2017-06-28 |
| 2017-06-29 |
| 2017-06-30 |
+------------+
30 rows in set (0.00 sec)
47/105
49. こんな キモい こともできる
1または0だからSUMがきく
mysql80 5> WITH RECURSIVE june AS (
-> SELECT CAST('2017/06/01' AS DATE) AS dt
-> UNION ALL
-> SELECT DATE_ADD(dt, INTERVAL 1 DAY) AS dt FROM june WHER
E dt < '2017/06/30')
-> SELECT SUM(WEEKDAY(dt) IN (5, 6)) AS not_working, SUM(WEEK
DAY(dt) NOT IN (5, 6)) AS working FROM june;
+-------------+---------+
| not_working | working |
+-------------+---------+
| 8 | 22 |
+-------------+---------+
1 row in set (0.01 sec)
48/105
55. 知ってると⾯⽩い
mysql80 5> SELECT * FROM t1;
+-----+------+
| num | val |
+-----+------+
| 1 | one |
| 2 | two |
+-----+------+
2 rows in set (0.01 sec)
mysql80 5> SELECT * FROM t1 WHERE num;
+-----+------+
| num | val |
+-----+------+
| 1 | one | <-- numは0じゃないので真
| 2 | two | <-- numは0じゃないので真
+-----+------+
2 rows in set (0.00 sec)
54/105
56. 知ってると⾯⽩い
mysql80 5> SELECT * FROM t1 WHERE num = TRUE;
+-----+------+
| num | val |
+-----+------+
| 1 | one | <-- TRUEは1だからnum = 1
+-----+------+
1 row in set (0.00 sec)
mysql80 24> SELECT * FROM t1 WHERE num IS TRUE;
+-----+------+
| num | val |
+-----+------+
| 1 | one | <-- 1 IS TRUE => 真
| 2 | two | <-- 2 IS TRUE => 真
+-----+------+
2 rows in set (0.02 sec)
55/105
60. NULLに対する演算(2)
mysql80 25> SELECT NULL AND NULL, NULL AND TRUE, NULL AND FALS
E, NULL OR NULL, NULL OR TRUE, NULL OR FALSEG
*************************** 1. row ***************************
NULL AND NULL: NULL
NULL AND TRUE: NULL
NULL AND FALSE: 0
NULL OR NULL: NULL
NULL OR TRUE: 1
NULL OR FALSE: NULL
1 row in set (0.00 sec)
59/105
61. NOT NULL推奨
ある整数Aは
A = 1 または A <> 1-
A == 1のテストとA == 0のテストを書けば境界値テストでカバーで
きる
-
ある整数型のNULLABLEなカラムに格納された値Bは
B = 1 または B <> 1 または B IS NULLである-
B == 1のテストとB == 0とdefined(B) == falseの3つのテストを
書かないといけない
-
60/105
67. シンタックス(4)
col_name | expr | position
GROUP BY や ORDER BY で指定するやつ-
カラム名、評価式、select̲list内のオフセット(1オリジン)で指定で
きる
-
ORDER BY RAND() なんてのは1⾏ごとに RAND() が⾛って、その結果
(0から1までのDOUBLE)でソートするからランダムな結果セットが
返る
-
ORDER BY NULL なんてキーワードもある-
expr の⽰す通り、値を返す式でもイケる-
66/105
68. ⾶び道具っぽいORDER BY指定
mysql80 5> SELECT * FROM t1;
+-----+-------+
| num | val |
+-----+-------+
| 1 | one |
| 2 | two |
| 3 | three |
| 4 | four |
| 5 | five |
+-----+-------+
5 rows in set (0.00 sec)
mysql80 5> SELECT num, val FROM t1 ORDER BY 2 DESC; -- select_listの2要素目=valのD
ESCソート
+-----+-------+
| num | val |
+-----+-------+
| 2 | two |
| 3 | three |
| 1 | one |
| 4 | four |
| 5 | five |
+-----+-------+
5 rows in set (0.00 sec)
67/105
69. ⾶び道具ORDER BYその2
mysql80 23> SELECT * FROM t1 ORDER BY FIELD (num, 1, 4, 5, 3, 2);
+-----+-------+
| num | val |
+-----+-------+
| 1 | one |
| 4 | four |
| 5 | five |
| 3 | three |
| 2 | two |
+-----+-------+
5 rows in set (0.03 sec)
mysql80 23> SELECT *, FIELD (num, 1, 4, 5, 3, 2) AS sort_expr FROM t1 ORDER BY FIEL
D (num, 1, 4, 5, 3, 2);
+-----+-------+-----------+
| num | val | sort_expr |
+-----+-------+-----------+
| 1 | one | 1 |
| 4 | four | 2 |
| 5 | five | 3 |
| 3 | three | 4 |
| 2 | two | 5 |
+-----+-------+-----------+
5 rows in set (0.00 sec)
68/105
70. NULLABLEなカラムのソート
mysql80 24> SELECT * FROM t1 ORDER BY num;
+------+------+
| num | val |
+------+------+
| NULL | NULL |
| 1 | one |
| 2 | two |
+------+------+
3 rows in set (0.00 sec)
mysql80 24> SELECT * FROM t1 ORDER BY num DESC;
+------+------+
| num | val |
+------+------+
| 2 | two |
| 1 | one |
| NULL | NULL |
+------+------+
3 rows in set (0.00 sec)
69/105
75. 闇なやつ
[SQL̲CALC̲FOUND̲ROWS]
ORDER BY .. LIMIT .. のbreakを無効にする代わりに、
COUNT(*) も⼀緒に取得する
取得した COUNT(*) は SELECT FOUND_ROWS() でアクセス可能-
2回テーブルスキャンするよりは速いけど、 ORDER BY ..
LIMIT .. の早抜けできなくなるので遅い
74/105
76. 闇なやつ
mysql80 7397205> SELECT * FROM city ORDER BY population DESC LIMIT 10;
..
10 rows in set (0.01 sec)
mysql80 7397205> SELECT FOUND_ROWS();
+--------------+
| FOUND_ROWS() |
+--------------+
| 10 |
+--------------+
1 row in set (0.00 sec)
mysql80 7397205> SELECT sql_calc_found_rows * FROM city ORDER BY population DESC
LIMIT 10;
..
10 rows in set (0.00 sec)
mysql80 7397205> SELECT FOUND_ROWS();
+--------------+
| FOUND_ROWS() |
+--------------+
| 4079 |
+--------------+
1 row in set (0.00 sec)
75/105