最初のクエリ
クエリが答えるのはひとつの質問です。どの行の、どの列がほしいのか。 いちばん短い聞き方が SELECT *(全部の列)と、FROM にテーブルをひとつ書く形です。
1
-- Every column of every product. Run it with F9 or Ctrl/Cmd + Enter.
SELECT *
FROM products
LIMIT 20;
結果 — 20 行のうち先頭 5 行
| id | category_id | name | description | sku | price | cost | stock_quantity | weight_kg | attributes | is_active | created_at | updated_at |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 16 | Glass Orchard (Paperback ed.) | Glass Orchard (Paperback ed.) — built to last. | SKU-00001 | 913.72 | 443.95 | 179 | 6.18 | {"color":"green","warranty_months":12,"material":"fabric"} | 1 | 2024-01-13 07:13:52 | 2024-01-13 07:13:52 |
| 2 | 17 | Luma The Gene | Luma The Gene — built to last. | SKU-00002 | 332.64 | 161.72 | 83 | 5.893 | {"color":"silver","warranty_months":24,"material":"steel"} | 1 | 2022-06-16 08:45:20 | 2022-06-16 08:45:20 |
| 3 | 21 | Quill Helmet | Quill Helmet — designed for daily use. | SKU-00003 | 196.26 | 118.25 | 399 | 8.261 | {"color":"silver","warranty_months":24} | 1 | 2022-08-26 20:06:03 | 2022-08-26 20:06:03 |
| 4 | 16 | Kite Glass Orchard 3 | Kite Glass Orchard 3 — built to last. | SKU-00004 | 1719.68 | 845.91 | 243 | 5.263 | {"color":"silver","warranty_months":24} | 0 | 2022-07-19 11:34:27 | 2022-07-19 11:34:27 |
| 5 | 17 | The Gene (3rd ed.) | The Gene (3rd ed.) — a dependable everyday choice. | SKU-00005 | 122.8 | 69.5 | 357 | 1.898 | {"color":"red","warranty_months":36,"material":"aluminium"} | 1 | 2022-05-21 10:53:40 | 2022-05-21 10:53:40 |
ブラウザの別タブで Planche が開き、サンプルデータベースを読み込んだ状態でこのクエリが入ります。このページの例はどれも同じタブを使い回します。F9 を押すまで実行はされません。
* は「全列」、LIMIT 20 は「最大20行」を意味します。テーブルの構造を確認するだけなら、products の数千行をすべて取得する必要はありません。取得した行は転送・描画されるためです。
Planche にも結果件数の上限があります(設定 › 安全性 › 行数上限)。ただしクエリに LIMIT を書けば、データベースが読むデータ量も意図どおりに抑えられます。
列を選ぶ
SELECT * はテーブルを確認するときに便利です。必要な内容が決まったら列名を明示してください。結果が読みやすくなり、転送するデータも減ります。
2
SELECT name, sku, price, stock_quantity
FROM products
LIMIT 20;
結果 — 20 行のうち先頭 5 行
| name | sku | price | stock_quantity |
|---|---|---|---|
| Glass Orchard (Paperback ed.) | SKU-00001 | 913.72 | 179 |
| Luma The Gene | SKU-00002 | 332.64 | 83 |
| Quill Helmet | SKU-00003 | 196.26 | 399 |
| Kite Glass Orchard 3 | SKU-00004 | 1719.68 | 243 |
| The Gene (3rd ed.) | SKU-00005 | 122.8 | 357 |
SELECT に書いた順が結果の列順になります。テーブル側の列順は関係ありません。結果の列名を変えるには AS を使います。
WHERE で行を絞る
SELECT が列を選び、WHERE が行を選びます。条件を受け取り、それが真になる行だけを残します。
3
SELECT name, price, stock_quantity
FROM products
WHERE price > 100
LIMIT 20;
結果 — 20 行のうち先頭 5 行
| name | price | stock_quantity |
|---|---|---|
| Lean Startup (Deluxe ed.) | 107.37 | 84 |
| Pixel Sofa | 108.18 | 7 |
| Terra Pillow Pro | 113.67 | 0 |
| Pulse LED Strip | 114.86 | 480 |
| Brief Answers (3rd ed.) | 117.96 | 194 |
比較演算子には =、<>(または !=)、<、<=、>、>= を使います。NULL の比較には別の規則があります。
- 等価は
=ひとつです。==ではありません。 - NULL とは何も等しくなりません。NULL 同士でもです。
WHERE weight_kg = NULLは、重量が記録されていない商品がいくつあっても1行も返しません。書きたい条件はIS NULL/IS NOT NULLです。次のレッスンできちんと扱います。
ORDER BY で並べ替える
ORDER BY を指定しない場合、返る行の順序は保証されません。順序が必要なら明示してください。データやインデックスが変われば、たまたま見えていた順序も変わります。
4
SELECT name, price
FROM products
ORDER BY price DESC
LIMIT 20;
結果 — 20 行のうち先頭 5 行
| name | price |
|---|---|
| Glide GPS Watch Pro | 2484.4 |
| Terra 3D Puzzle | 2481.77 |
| Aria Castle Kit | 2479.41 |
| Aria LED Strip Pro | 2463.41 |
| Nova Brief Answers | 2445.49 |
DESC は大きい順、ASC(既定)は小さい順です。ORDER BY price DESC と LIMIT 20 を組み合わせると、価格の高い順に20件を取得できます。まず全体を並べ替え、その後で先頭20行を取ります。
Planche では結果グリッドの列見出しをクリックして並べ替えることもできます。昇順、降順、解除の順に切り替わり、サーバー側で再取得されます。
複数の列で並べ替える
並べ替えキーを複数指定すると、前のキーで同じ値だった行を次のキーで並べ替えます。
5
SELECT category_id, name, price
FROM products
ORDER BY category_id, price DESC
LIMIT 30;
結果 — 30 行のうち先頭 5 行
| category_id | name | price |
|---|---|---|
| 2 | Aria Notebook | 2116.4 |
| 2 | Ember Laptop Plus | 2087.98 |
| 2 | Sol Notebook | 1982.34 |
| 2 | Sol Ultrabook | 1942.47 |
| 2 | Nimbus Ultrabook | 1933.06 |
このクエリはカテゴリ順に並べ、その中では価格の高い商品を先に表示します。
式と別名
SELECT に書けるのは列だけではありません。四則演算でも関数呼び出しでも、行ごとに値を作るものなら書けます。そして AS がその結果に名前を付けます。
6
SELECT name,
price,
cost,
ROUND(price - cost, 2) AS margin
FROM products
WHERE is_active = 1
ORDER BY margin DESC
LIMIT 15;
結果 — 15 行のうち先頭 5 行
| name | price | cost | margin |
|---|---|---|---|
| Ember Tab Plus | 2412.93 | 984.94 | 1427.99 |
| Aria LED Strip Pro | 2463.41 | 1098.69 | 1364.72 |
| Luma Denim Jacket Pro | 2357.59 | 993.24 | 1364.35 |
| Drift A Winter Letter | 2422.5 | 1082.43 | 1340.07 |
| Nova Brief Answers | 2445.49 | 1108.09 | 1337.4 |
ROUND(price - cost, 2) AS margin は、テーブルのどこにも存在しない列を計算しています。そして margin という名前は ORDER BY で使えます。しかし WHERE では使えません。ここは本当によく引っかかるところです。理由は、データベースが句を評価する順序にあります。
FROM -> WHERE -> SELECT -> ORDER BY -> LIMIT
ORDER BY が動くころには SELECT が margin を作り終えています。WHERE が動く時点ではまだ存在しないので、WHERE margin > 50 はエラーになります。式をもう一度書くか、クエリ全体をもうひとつのクエリで包むしかありません。この順序は覚えておいてください。WHERE がグループ化の前に行を絞り、HAVING が後で絞る理由も同じ順序で説明がつきます。それは2つ先のレッスンです。
ここまでで書けるもの
この4つの句だけでも、現実の質問にかなり答えられます。高い順に20商品、在庫切れの一覧、販売中の商品で利益率が高いもの。まだできないのは、2つのテーブルにまたがる質問です。どの顧客がどの注文をしたか。そのための道具が結合です。
次に進む前に、上の例題の数字や列名を書き換えて実行し直してみてください。グリッドはその場で更新されるので、試す速度はかなり速いはずです。