SQL - git0331-lgtm/Knowledge GitHub Wiki

DML

---------------------------------------------------------------------------------------------------------------------------------
select ・・・ select 列名 or 計算式 or 固定値 or 関数 * from テーブル名
※ 列名   : 列の内容
※ 計算式 : 計算式の評価結果
※ リテラル : リテラル
※ 関数 : 実行結果
※ from 省略  : テーブルデータ非参照の時に可能(ex, 既存のデータを使用しない計算結果のみ or リテラルのみ or 計算結果とリテラルの組み合わせ)
---------------------------------------------------------------------------------------------------------------------------------
update ・・・ update テーブル名 set 列名1 = 値, 列名2 = 計算式
---------------------------------------------------------------------------------------------------------------------------------
delete ・・・ delete from テーブル名
---------------------------------------------------------------------------------------------------------------------------------
insert ・・・ insert into テーブル名 (列名1, 列名2, 列名3) values (値, 値, 値 or 計算式, 計算式, 計算式)
※ (列名1, 列名2, 列名3) は全列データ挿入時に省略可能
---------------------------------------------------------------------------------------------------------------------------------

修飾子 ・ 演算子

---------------------------------------------------------------------------------------------------------------------------------
[対象行の絞り込み]
where  ・・・ 対象行の絞り込み(ex, where 列名 = 1000)
---------------------------------------------------------------------------------------------------------------------------------
[真偽値]
比較演算子
=       ・・・ 左右の値が等しい 
<>      ・・・ 左右の値が等しくない
>       ・・・ 左辺が右辺より大きい
<       ・・・ 左辺が右辺より小さい
>=      ・・・ 左辺が右辺以上
<=      ・・・ 左辺が右辺以下

論理演算子
and    ・・・ すべて真のときに真(ex, select 列名 from テーブル名 where 条件式 and 条件式)
or     ・・・ いずれか真のときに真(ex, select 列名 from テーブル名 where 条件式 or 条件式)
not    ・・・ 真偽値の逆転(ex, select 列名 from テーブル名 where not 条件式)
※ (where not 列名 = 値) と (where 列名 <> 値)
※ 優先順位 : not → and → or  ()で括って変更可

is null     ・・・ null判定(ex, select 列名 from テーブル名 where 列名 is null)
is not null ・・・ null判定(ex, select 列名 from テーブル名 where 列名 is not null)

like        ・・・ パターンマッチング(ex, select 列名 from テーブル名 where 列名 like '%1月%')
between     ・・・ 以上~以下(ex, select 列名 from テーブル名 where 列名 between 値 and 値)

in          ・・・ in 内のいずれかの値に等値か判定(ex, select 列名 from テーブル名 where 列名 in (値, 値, 値・・・))
not in      ・・・ not in 内のすべての値に不等値か判定(ex, select 列名 from テーブル名 where 列名 not in(値, 値, 値・・・))
any         ・・・ any 内の複数のいずれかと大小該当するか判定(ex, select 列名 from テーブル名 where 列名 比較演算子 any (値, 値, 値))
all         ・・・ all 内の複数の全ての値と大小該当するか判定(ex, select 列名 from テーブル名 where 列名 比較演算子 all (値, 値, 値))
※ (列名 in  (値, 値, 値)) と (列名 = any (値, 値, 値))
※ (列名 not in  (値, 値, 値)) と (列名 <> all (値, 値, 値))
※ in演算子・not in演算子 は単一の列を対象に指定可(複数不可)
---------------------------------------------------------------------------------------------------------------------------------
[計算式]
算術演算子
+       ・・・ 数値同士の足し算, 日付を指定日数だけ進める
-       ・・・ 数値同士の引き算, 日付を指定日数だけ戻す, 日付の差の日数を得る
*       ・・・ 数値同士の掛け算
/       ・・・ 数値同士の割り算
|| or + ・・・ 文字列連結
---------------------------------------------------------------------------------------------------------------------------------
[条件式]
case    ・・・ 条件ごとに値変換

(ex, case  列名 or 式 when 値1 then 返す値         (ex, case when 式1 then 返す値
                      when 値2 then 返す値                    when 式2 then 返す値
                      else デフォルト値                        else デフォルト値
                      end                )                   end                )
---------------------------------------------------------------------------------------------------------------------------------
[列名操作]
as     ・・・ 別名定義(ex, select 列名 as 別の列名 from テーブル名 as 別のテーブル名)
※ 省略      : DBMSによって省略可能な場合がある
※ Oracle DB : テーブル名の as は付けない
---------------------------------------------------------------------------------------------------------------------------------
[エスケープ]
escape ・・・ エスケープ宣言(ex, select 列名 from テーブル名 like 列名 '%100$%' escape '$')

関数

---------------------------------------------------------------------------------------------------------------------------------
[文字列]
length or len ・・・ 文字列の長さ取得(ex, length(文字列を表す列名) => 文字列の長さを表す数値)

trim          ・・・ 文字列の先頭・末尾の空白文字除去 (ex, trim(列名) => 先頭・末尾から空白を除去した文字列)
ltrim         ・・・ 文字列の先頭の空白文字除去      (ex, ltrim(列名) => 先頭から空白を除去した文字列)
rtrim         ・・・ 文字列の末尾の空白文字除去      (ex, rtrim(列名) => 末尾から空白を除去した文字列)
※ 使用場面 : char型の値

replace ・・・ 文字列置換(ex, replace(列名, 置換前の部分文字列, 置換後の部分文字列) => 置換処理後の文字列)

substring or substr ・・・ 文字列抽出(ex, substring or substr(列名, 抽出開始位置, 抽出終了位置) => 抽出処理後の文字列)

concat ・・・ 文字列連結(ex, concat(列名 or 文字列, 文字列, <文字列>・・・) => 連結処理後の文字列)
※ 3つ以上連結可 : SQLServer と MySQL
※ select concat(列名, ':' || 列名) as 新列名 from テーブル名
※ nullを含む場合 : 戻り値がnullとなるDBMSもある

string_agg ・・・ 列データ連結(ex, select stringagg(列名, '・') from テーブル名);
※ null は無視
---------------------------------------------------------------------------------------------------------------------------------
[数値]
round ・・・ 四捨五入(ex, round(列名 or 数値, 有効桁数) => 四捨五入した値)
※ 指定した数値目で処理
※ 有効桁数が正 : 少数部の桁数目
※ 有効桁数が負 : 整数部の桁数目
※ 0           : 少数点第0位

round(12345.678, 0) -- 12346
round(12345.678, -1) -- 12350 
round(12345.678, 1) -- 12345.7

trunc ・・・ 切り捨て(ex, trunc(列名 or 数値, 有効桁数) => 切り捨てた値)
※ 指定した数値目で処理
※ 有効桁数が正 : 少数部の桁数目
※ 有効桁数が負 : 整数部の桁数目
※ 0           : 少数点第0位

trunc(12345.678, 0) -- 12345
trunc(12345.678, -1) -- 12340 
trunc(12345.678, 1) -- 12345.6

power ・・・ べき乗(ex, power(列名, 何乗するかを指定する数値)=> べき乗した数値)
---------------------------------------------------------------------------------------------------------------------------------
[日付]
current_timestamp : 現在日時(年, 月, 日, 時, 分, 秒)
current_date      : 現在日付(年, 月, 日)
current_time      : 現在時刻(時, 分, 秒)
※ () は不要

datepart ・・・ 日付から月取得(ex, datepart(month, 日付) => 日付から取得した月)
---------------------------------------------------------------------------------------------------------------------------------
[変換]
cast : (ex, cast(変換する値 as 変換する型) => 変換後の値)

coalesce : (ex, coalesce(値1 or 式1 or null, 値2 or 式2 or null, 値3 or 式3 or null ・・・) => 引数の内、最初に現れたnullでない引数)
           (ex, coalesce(列名, 値 ・・・) => 列名の値が出力 ただし null の場合は値(初期値)になる)
※ 引数      : 任意の数
※  引数の型   : 全て一致

修飾子・演算子(select)

-----------------------------------------------------------------------------------------------------------------------------------------------------------------
[検索結果の加工]
distinct ・・・ 重複行の削除(ex, select distinct 列名 from テーブル名 where ・・・)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
order by ・・・ 昇順・降順(ex, select 列名 from テーブル名 where 条件 order by 列名1 or 列番号1 or 式1 asc or desc, 列名2 or 列番号2・・・ 
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
offset - fetch ・・・ 行数限定(ex, select ・・・ orderby ・・・ offset 先頭から除外する行数 rows fetch next 取得行数 rows only
※ 除外したい行がない場合   : offset句 省略可の場合あり(同義 : offset 0 rows)
※ 除外後すべての行を取得   : fetch句 省略可の場合あり
※ SQL Server 以外         : orderby なしで offset - fetch のみでも使用可能
※ その他の方法             : top(SQL Server), limit(MySQL, MariaDB, PostgreSQL, SQLite, H2 Databae), row()_number(SQLite以外), rownum(Oracle DB)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
union                     ・・・ 和集合(ex, select 文1 union or union(all) select 文2)
except / minus            ・・・ 差集合(ex, select 文1 except or except(all) select 文2)
intersect                 ・・・ 積集合(ex, select 文1 intersect or intersect(all) select 文2)
※ 列数とデータ型                        : 一致必須
※ orderby                              : 最後の select文 に記述
※ 列番号以外で並び替え(列名 or as 別名) : 最初の select文 に記述したものを指定
※ 列数不一致                            : null や その他のリテラルを追加 
(ex, select 列名1, 列名2 from テーブル名1 union select 列名1, null as 列名2 from テーブル名2;)
(ex, select 列名1, 列名2 from テーブル名1 union select 列名1, 'default value' as 列名2 from テーブル名2;)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------

関数(select)

---------------------------------------------------------------------------------------------------------------------------------
[集計関数]
sum     ・・・ 各行の値の合計の値
avg     ・・・ 各行の値の平均値
max     ・・・ 各行の値の最大値
min     ・・・ 各行の値の最小値
count   ・・・ 行数の数

[引数]
sum     ・・・ 数値型
avg     ・・・ 数値型
max     ・・・ 数値型・文字列型・日付型
min     ・・・ 数値型・文字列型・日付型
count   ・・・ 全てのデータ
※ 1つの列名のみ可
※ 列名を含む式も可

[null の取り扱い]
集計時
sum・avg・max・min  : null を含まず集計
count(列名)          : null を含まずカウント
count(*)              : null を含んでカウント

全行が null の場合
sum・avg・max・min   : null
count(列名)          : 0
count(*)             : 全行数

[グループ化]
(ex, select グループ化の基準列1, グループ化の基準列名2, 集計関数 from テーブル名 where 条件式 group by グループ化の基準列名1, グループ化の基準列名2)
※ 複数列指定 : 複数の列の組み合わせでデータをグループ化し、各グループに対して集計を行う
※ グループ化は group by に指定した列の順に行われる
※ select の選択列リストに指定する列は group by で指定されている  もしくは 集計関数で使用されていなければならない

[処理順序]
1. データ取得(from句)
データソーステーブルから全データを取得 ・・・ 表1

2. テーブル結合(join - on)
結合した表作成 ・・・ 表2

3. where がある場合は絞り込みを行う(where句)
絞り込みを行う ・・・ 表3

4. group by がある場合はグループ化を行う(group by句)
グループ化を行う ・・・ 表4

5. select に 集計関数 がある場合は集計処理を行う(select句)
6. select の処理を行う(列名, 関数, 計算式, リテラル, case・・・)(select句)
※ 3. group by がない場合 : 単一の表に対して実行 ・・表5
※ 3. group by がある場合 : グループの数(複数の表)に対して実行 ・・表5

7. having がある場合は絞り込みを行う(having句)
絞り込みを行う ・・・ 表6

8. order by, offset - fetch がある場合は処理を行う
加工を行う ・・・ 表7

9. distinct がある場合は処理を行う
※ 3. group by がある場合 : 無視
※ 重複行削除を行う ・・・ 表8

10. 結果表(表8)
※ グループ化の指定列が1つの場合 : 最大値は指定列の種類数
※ グループ化の指定列が複数の場合 : 最大値は指定列の種類数の乗算数
---------------------------------------------------------------------------------------------------------------------------------

副問い合わせ

単一行副問い合わせ ・・・ スカラ(1行1列)が求められる位置
複数行副問い合わせ ・・・ リスト(n行1列)が求められる位置
表副問い合わせ    ・・・  表(n行m列)が求められる位置
実行順序 ・・・ 内部クエリ → 外部クエリ

行値式 ・・・ 複数の列の値を一つのセットとして扱い、そのセット全体で比較
相関問い合わせ ・・・ 外部クエリの行が内部サブクエリの条件に依存している(実行順序 : 外部クエリ → 内部クエリ)
(ex, select 列名 from テーブル名 where (列名1, 列名2) in ((値1, 値2), (値3, 値4) )))
(ex, select 列名 from テーブル名 where (列名1 = 値1 and 列名2 = 値2) or (列名1 = 値3 and 列名2 = 値4))

(ex, with CTE名 as (select 値1 as 列1, 値2 as 列2 union(all) select 値3, 値4) 
          select from テーブル名 as t join CTE名 as v on t.列1 = v.列1 and t.列2 = v列2)

(ex, select t.* from テーブル名 as t 
        join (select '値1a' as 列1, '値2a' as 列2 union(all) select '値1b', '値2b') as v on t.列1 = v.列1 and t.列2 = v.列2)

(ex, with CTE名 as (select 値1 as 列1, 値2 as 列2 union(all) select 値3, 値4)
          select t.* from テーブル名 as t where exists(t.列1 = v.列1 and t.列2 = v.列2))

テーブル結合

inner join on ・・・ 内部結合 / 結合可能な行(条件該当行)のみ出力(ex, select 列名 from テーブル名 join テーブル名 on 結合条件)(※1)

left outer join on ・・・ 左外部結合 / 結合元(左表)の行は増減させない(ex, select 列名 from テーブル名 left outer join テーブル名 on 結合条件)
right outer join on・・・ 右外部結合 / 結合元(右表)の行は必ず全て出力する(ex, select 列名 from テーブル名 right outer join テーブル名 on 結合条件)

full join on ・・・ 左外部結合 + 右外部結合(ex, select 列名 from テーブル名 full join テーブル名 on 結合条件)(※2)

※1 結合相手が 存在しない or null の場合
結合元の行(左表)に対して 条件該当行が 結合相手内(右表)に 存在しない場合
結合元の行(左表)が null の場合
→ その行は削除される

※2 union
full join は left outer join union right outer join に置き換え可能

※3 結合相手が複数の場合
結合元の行(左表)に対して 条件該当行 が 結合相手内(右表)に 複数ある場合
→ 結合元(左表)の行をコピーして増やす

※4 3テーブル以上の結合
※5 サブクエリ結果との結合
※6 自己結合 / 再帰結合

トランザクション

[構文]
BEGIN TRANSECTION; -- 自動コミット解除
SET TRANSACTION ISOLATION LEVEL 分離レベル名; -- レベル指定

-- 処理1
-- 処理2

COMMIT; -- トランザクションの成功時


ROLLBACK; -- エラー発生時のロールバック

[副作用名称]
ダーティーリード ・・・ コミット前の情報を他の人が読めてしまう問題
反復不能読み取り ・・・ 複数のselect文の間でupdate文が入ると問題
ファントムリード ・・・ 複数のselect文の間でinsert文が入ると取得行数が変わってしまう問題

[トランザクション分離レベル]
[適用範囲 ・・・ トランザクション内のSQL文]

READ UNCOMMITTED
許可 : SELECT(未コミット・コミット済みデータ)・UPDATE・INSERT
禁止 : なし
危険 : ダーティーリード・反復不能読み取り・ファントムリード
備考1 : 【他のトランザクション】が【現在のトランザクションが操作している行で未コミットのデータ取得】できてしまう。
備考2 : 【他のトランザクション】は【現在のトランザクションが操作している行に対して更新・挿入】できてしまう。
備考3 : 【現在のトランザクション】は【他のトランザクションの処理途中のデータ(未コミットデータ含む)】を取得できてしまう。 

READ COMMITTED(初期レベル)
許可 : SELECT(コミット済みデータ)・UPDATE・INSERT
禁止 : SELECT(未コミットデータ) 
危険 : 反復不能読み取り・ファントムリード
備考1 : 【他のトランザクション】が【現在のトランザクションが操作している行で未コミットのデータ取得】を防ぐ。  
備考2 : 【他のトランザクション】は【現在のトランザクションが操作している行に対して更新・挿入】できる。
備考3 : 【現在のトランザクション】は【他のトランザクションが更新・挿入したデータ】を取得する恐れがある。


REPEATABLE READ
許可 : SELECT(コミット済みデータ)・INSERT
禁止 : SELECT(未コミットデータ)・UPDATE
危険 : ファントムリード
備考1 : 【他のトランザクション】が【現在のトランザクションが操作している行で未コミットのデータ取得】を防ぐ。
備考2 : 【他のトランザクション】が【現在のトランザクションが操作している行に対しての更新】を防ぐ。
備考3 : 【他のトランザクション】は【現在のトランザクションが操作している行に対して挿入】できてしまう。
備考4 : 【現在のトランザクション】は【他のトランザクションが挿入したデータ】を取得する恐れがある。


SERIALIZABLE
許可 : SELECT(コミット済みデータ)
禁止 : SELECT(未コミットデータ)・UPDATE・INSERT
危険 : なし
備考1 : 【他のトランザクション】が【現在のトランザクションが操作している行の未コミットのデータ取得】を防ぐ。
備考2 : 【他のトランザクション】が【現在のトランザクションが操作している行に対しての更新・挿入】を防ぐ。

[明示的なロック]
[適用範囲 ・・・ 行/テーブル/DB]

行
共有ロック ・・・ 読み取り可・更新と挿入不可・他からの共有ロックを許可(ex, WITH (HOLDLOCK, NOWAIT) )
排他ロック ・・・ 読み取りと更新と挿入と他からのロックを制限(最強)(ex, WITH (TABLOCK, NOWAIT) )

テーブル
共有ロック ・・・ 読み取り可・更新と挿入不可・他からの共有ロックを許可(ex, LOCK TABLE テーブル名 IN SHARE MODE (NOWAIT) )
排他ロック ・・・ 読み取りと更新と挿入と他からのロックを制限(最強)(ex, WITH (TABLOCKX, NOWAIT) )

DB単位

デッドロック
予防 ・・・ トランザクション時間を短くする / 同じ順番でロックする

ロックエスカレーション
負荷軽減の為、ロック対象が多い場合は自動的にテーブルロックに切り替わる

パターン文字

% ・・・ 任意の0文字
_ ・・・ 任意の1文字

コメント

--    ・・・ 行末コメント
/* */ ・・・  区切りコメント

Tips

---------------------------------------------------------------------------------------------------------------------------------
日指定 ・・・ 2024年4月15日               (ex, 日付 = '2024-04-15')
週指定 ・・・ 2024年4月8日 - 4月14日      (ex, 日付 > '2024-04-07' AND 日付 < '2024-04-15')
月指定 ・・・ 2024年4月                   (ex, 2024-03-31 < 日付 && 2024-05-01 > 日付)
年指定 ・・・ 2024年1月1日 - 2024年12月31日(ex, 日付 > '2023-12-31' AND 日付 < '2025-01-01')

第1四半期 ・・・ 2024年1月1日 - 3月31日(ex, 日付 > '2023-12-31' AND 日付 < '2024-04-01')
第2四半期 ・・・ 2024年4月1日 - 6月30日(ex, 日付 > '2024-03-31' AND 日付 < '2024-07-01')
第3四半期 ・・・ 2024年7月1日 - 9月30日(ex, 日付 > '2024-06-30' AND 日付 < '2024-10-01')
第4四半期 ・・・ 2024年10月1日 - 12月31日(ex, 日付 > '2024-09-30' AND 日付 < '2025-01-01')
---------------------------------------------------------------------------------------------------------------------------------
文字列の末尾から指定 ・・・(ex, substring(文字列, trim(文字列)-1, 2) ・・・ xxxxxxxXX XXを抜き出す)
---------------------------------------------------------------------------------------------------------------------------------
商品一覧   ・・・(ex, select distinct 列名 from テーブル名;)
商品数     ・・・(ex, select count(distinct 列名) from テーブル名;)
商品区分ごと合計数 ・・・ (ex, select 列名, count(*) from テーブル名 group by 列名)
---------------------------------------------------------------------------------------------------------------------------------
null 潰し ・・・ 
select avg(coalesce(出金額, 0)) as 出金額合計 from 出金履歴;
select 列名 from テーブル名 where select 費目 from テーブル名 where 費目 is not null;
select 列名 from テーブル名 where 列名 in (select colalesce(費目, '不明') from テーブル名);
---------------------------------------------------------------------------------------------------------------------------------
coalesce と case-when ・・・ nullの場合の初期値を else なしで設定できる
---------------------------------------------------------------------------------------------------------------------------------

ひな形

< pre >
---------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------
< /pre >
⚠️ **GitHub.com Fallback** ⚠️