MW211 EXIT

devlog
SQL/アクセス修飾子
2012年08月19日
viewの内部で使用するviewにはprivateアクセス修飾子をつけたいものだ。
publicなviewを生成する過程なんだから、非公開でいいじゃんという。
publicなviewとprivateなviewを明示的に選別できれば
制作者の意図がある程度明快になる。
今のところそんな動きはないが、そのうちそういう仕様になってくれないかな。。。
分類:SQL
SQL/define定数
2012年08月18日
SQL文実行や、VIEW定義でdefine定数は使えない。
ま、べた書きの数字にコメントつけろってこった。
分類:SQL
SQL/条件の組合せ
2012年08月13日
○=TRUE(一致)、?=UNKNOWN(NULL混在)、×=FALSE(不一致)
    ┌─┐    ┌─┬─┬─┐    ┌─┬─┬─┐
    │!│  &│○│?│×│  OR│○│?│×│
┌─┌─┐┌─┌─┬─┬─┐┌─┌─┬─┬─┐
│○│×││○│○│?│×││○│○│○│○│
├─├─┤├─├─┼─┼─┤├─├─┼─┼─┤
│?│?││?│?│?│×││?│○│?│?│
├─├─┤├─├─┼─┼─┤├─├─┼─┼─┤
│×│○││×│×│×│×││×│○│?│×│
└─└─┘└─└─┴─┴─┘└─└─┴─┴─┘
分類:SQL
SQL/MAX()について
2012年08月07日
MAX()のあれこれ(たぶんMIN()も同様だと思う)。

数値型でも文字型でもOK。
○SELECT MAX(1);     → 1
○SELECT MAX('a');   → a
○SELECT MAX(NULL);  → NULL

ワイルドカード(*)は一律使えないみたい。
○SELECT MAX(z) FROM (SELECT 1 AS z) AS a;
×SELECT MAX(*) FROM (SELECT 1 AS z) AS a;
上記の場合、単一列なのにエラーとなった。


判定する行がない場合は、NULLとなる。
○SELECT MAX(z) FROM (SELECT 1 AS z WHERE FALSE) AS a;  → NULL

判定する列が全てNULLだった場合には、NULLとなる。
○SELECT MAX(z) FROM (SELECT NULL::numeric AS z) AS a;  → NULL
分類:SQL
SQL/副問い合わせ(3)
2012年08月01日
「単一行」副問い合わせは、対象とする表が複数行の表であっても
選択(SELECTの行数)によって、単一行となった場合には成立する。
  ○SELECT * FROM 単一行表
  ○SELECT * FROM 複数行表 WHERE 列 = 一意値
  ×SELECT * FROM 複数行表 WHERE 列 = 非一意値
これは実際のデータに左右されるので、やってみないとわからない。
(やった瞬間の状態に依存する)
例えば、ある列について、行1にのみ「A」という値が入っている場合に
その列に対して「A」を条件に抽出(選択)を行えば「単一行」副問い合わせが成立する。
しかし、直後に行2にも「A」という値を入れて再度SQL文を実行した場合、
今度は「単一行」副問い合わせが成立しなくなる。

ということで、「単一行」副問い合わせが成立するか否かは
事前に厳密に精査しておかねばならない。
基本的に(条件にNULLが絡まない限り)UNIQUE属性の列を
抽出条件の対象としておけば問題ないだろう。
分類:SQL
SQL/副問い合わせ(2)
2012年07月31日
「単一列」副問い合わせは、対象とする表が複数列の表であっても
射影(SELECTの列数)によって、単一列になることが保証されれば成立する。
  ○SELECT 列 FROM 表
  ○SELECT * FROM 単一列表
  ×SELECT * FROM 複数列表
実際にデータがあろうがなかろうが理論上で単一列であることが決定できる。
分類:SQL
SQL/副問い合わせ(1)
2012年07月30日
副問い合わせはその結果により、以下の五種類に分類できる。
┌──────┬──────┬──────┐
│            │単一行単一列│単一行複数列│
│  該当なし  ├──────┼──────┤
│            │複数行単一列│複数行複数列│
└──────┴──────┴──────┘

副問い合わせが成立するのは以下の場合(○=成立、×=エラー)
【結果列に副問い合わせを出力する場合】
    ○SELECT (該当なし);  ※
    ○SELECT (単一行単一列);
    ×SELECT (複数行);
    ×SELECT (複数列);
  ※該当なしの場合は、NULL扱いとなる
    ちなみに型は該当ありだった場合の列の型となる
【条件式に副問い合わせを出力する場合】
    ○SELECT 列 FROM 表 WHERE 列 = (該当なし);  ※
    ○SELECT 列 FROM 表 WHERE 列 = (単一行単一列);
    ×SELECT 列 FROM 表 WHERE 列 = (複数行);
    ×SELECT 列 FROM 表 WHERE 列 = (複数列);
    ○SELECT 列 FROM 表 WHERE 列 IN (該当なし);  ※
    ○SELECT 列 FROM 表 WHERE 列 IN (単一列);
    ×SELECT 列 FROM 表 WHERE 列 IN (複数列);
  ※該当なしの場合はNULL扱いなので、条件式にNULLが混在することになり
    その結果、判定結果は「偽」になる
分類:SQL
SQL/NULLの法則
2012年07月29日
NULLは「''」や「0」と混同してしまいがちだが、
以下の性質があるので押さえておくと何かと役立つ。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
┌──────────────────────────────────────┐
│NULLが加減乗除の一要素となった場合、計算結果がNULLになる                    │
└──────────────────────────────────────┘
  なお、「1/NULL」のように除算しても除数ゼロエラーではなく計算結果がNULLとなる。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
┌──────────────────────────────────────┐
│NULLに文字列結合した場合、結合結果がNULLになる                              │
└──────────────────────────────────────┘
  「NULL || 'a'」の結果は「'a'」ではなく「NULL」。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
┌──────────────────────────────────────┐
│NULLの型は不明型(unknown)だが、キャストもできる                             │
└──────────────────────────────────────┘
  「NULL::integer」のようにキャストするとその型(integer型)のNULLとなる。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
┌──────────────────────────────────────┐
│NULLを判定するとたいてい偽になる                                            │
└──────────────────────────────────────┘
  ・CASE WHEN NULL = 0 THEN '真' ELSE '偽' END  →  偽
  ・CASE WHEN NULL > 0 THEN '真' ELSE '偽' END  →  偽
  ・CASE WHEN NULL < 0 THEN '真' ELSE '偽' END  →  偽
  加減乗除の結果もNULLとなるという法則を組み合わせると以下も導き出せる。
  ・CASE WHEN (NULL + 1) > 0 THEN '真' ELSE '偽' END  →  偽
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
┌──────────────────────────────────────┐
│NULLを判定するためには「IS NULL」を使わなければならない                     │
└──────────────────────────────────────┘
  「NULL IS NULL」は真だが、「NULL = NULL」は偽。
  ちなみに「NULL IS NOT NULL」は偽だが、「NULL <> NULL」も偽。
  さらには、「IN (NULL)」も「NOT IN (NULL)」も偽。
  NULLに対しては「IS NULL」や「IS NOT NULL」を使わないと一律に偽になる。
分類:SQL
SQL/内訳数
2012年06月30日
┌──────────────────────────────────────┐
│a                                                                           │
│└b                                                                         │
│  └c                                                                       │
└──────────────────────────────────────┘
上記のような階層になっていて、a毎の内訳数をそれぞれで得たいとき。

以下のようにやってはダメ。
┌──────────────────────────────────────┐
│SELECT a.id,                                                                │
│       COUNT(b.*) AS count_b,                                               │
│       COUNT(c.*) AS count_c                                                │
│    FROM a                                                                  │
│        LEFT JOIN b ON b.a_id = a.id                                        │
│        LEFT JOIN c ON c.a_id = a.id                                        │
│    GROUP BY a.id                                                           │
└──────────────────────────────────────┘
「count_b」も「count_c」もおっきな数になる(a×b×cの組み合わせ総数になる)。

以下のようにすればよい。
┌──────────────────────────────────────┐
│SELECT a.id,                                                                │
│       COUNT(DISTINCT b.*) AS count_b,                                      │
│       COUNT(DISTINCT c.*) AS count_c                                       │
│    FROM a                                                                  │
│        LEFT JOIN b ON b.a_id = a.id                                        │
│        LEFT JOIN c ON c.a_id = a.id                                        │
│    GROUP BY a.id                                                           │
└──────────────────────────────────────┘
分類:SQL
SQL/【未解決】集合関数の組み合わせ
2012年06月26日
集約関数を複合させて使う場合
┌──────────────────────────────────────┐
│SELECT SUM(列1),                                                            │
│       MAX(列2)                                                             │
│    FROM 表;                                                                │
└──────────────────────────────────────┘
みたいに、合計値と最大値を同時に求めることはできる。

┌──────────────────────────────────────┐
│SELECT SUM(列1),                                                            │
│       MAX(列2),                                                            │
│       列3                                                                  │
│    FROM 表;                                                                │
└──────────────────────────────────────┘
みたいに、最大値をもつ列の別項目を取得するのはできるのだろうか?
分類:SQL、【未解決】
前へ 1 2 3 4 5 6 次へ