📖

達人に学ぶSQL徹底指南書をTiDB Serverlessで写経する(1)

2024/01/15に公開

TiDBはMySQL互換ということになっているが、実際どのくらい問題ないのかを検証するべく、書籍に記載のSQLを実際に実行して確かめてみる。動かす時に修正が必要だった箇所についてはメモを記載した。

https://www.shoeisha.co.jp/book/detail/9784798157825

まずは第一章の6まで。

第1章 魔法のSQL

1. CASE式のススメ

CHECK制約で複数の列の条件関係を定義する

  • P.11 CHECK制約はMySQL 8.0 では利用できないと記載あるが、MySQL 8.0.16以降で利用できる。
    • TiDBではCHECK制約はTiDB > v7.2 から有効にできる。
    • SET GLOBAL tidb_enable_check_constraint=1; を実行する必要がある。
    • ただTiDB Serverlessは2023年12月時点ではv6.6のため利用できない。
    • OSS版のTiDB Playgroundで正しく動作することを検証済み。

演習問題

  • P.23 keyはMySQL/TiDBで予約語のためそのままでは列名として利用できない。バックティックでくくる必要がある。

2. 必ずわかるウィンドウ関数

重複行を削除する

  • P.49 TiDBでは主キーを定義していないときは自動的に主キーが作成され、_tidb_rowid で参照できる。これをrowid代わりに利用できる。これを使った重複行削除は下記のようになる。
    DELETE FROM Products P1 
     WHERE _tidb_rowid < ( SELECT MAX(P2._tidb_rowid) 
    		   FROM Products P2 
    		  WHERE P1.name = P2. name 
    		    AND P1.price = P2.price );
    

3. 自己結合の使い方

問題なし

4. 3値論理とNULL

文字列とNULL

  • P.78 MySQLとTiDBの文字列連結を標準SQLのように ||で行うには、SET sql_mode='ANSI'; や、 SET sql_mode='PIPES_AS_CONCAT' を行う必要がある。そうしないとORの別名として扱われる

演習問題

  • P.83 MySQLもTiDBも COALESCE関数とNULLIF関数を持つ

この章は実務上で非常に役に立つと感じた。論理演算や限定子、集計演算にNULLが含まれるとどうなるかは初見だとほぼ理解できない。

5. EXISTS述語の使い方

列に対する量化 - オール1の行を探せ

  • P.100 MySQLのALLやANYはサブクエリーにしか適用できないため、「全ての列が1である」ような行の抽出は困難。
    • 「どこかの列が9である」ような行の抽出はINで出来る
    • Stack Overflowにも議論があり、ここを参考に下記のように全ての列を連結して文字列で比較するという方法を思いついた。重そうだなあ。
      SELECT *
        FROM ArrayTbl
      WHERE '1111111111' = CONCAT_WS('',col1, col2, col3, col4, col5, col6, col7, col8, col9, col10);
      

演習問題

  • P.103 keyは予約語なのでバックティックで囲う必要がある。

6. HAVING句の力

問題なし
非常に実用的な例の多い章で一読をお勧め。

Discussion