MW211 EXIT

devlog
PostgreSQL/続・NULLの処遇のおさらい
2013年02月02日
ついでに、グループごとの最大値もしくは最小値を含む明細を抽出する場合に
NULLを最劣後にするSQL文も記録にとどめておこう。

まずは最小値を含む明細を求める方法。
┌──────────────────────────────────────┐
│SELECT DISTINCT ON ("k") "k","c","s"                                        │
│    FROM (VALUES ('g',1,'a'),('g',2,'b'),('g',NULL,'c')) AS "t"("k","c","s")│
│    ORDER BY "k"         ASC,                                               │
│             "c" IS NULL ASC,                                               │
│             "c"         ASC;                                      →(g,1,a)│
└──────────────────────────────────────┘

次に最大値を含む明細を求める方法。
┌──────────────────────────────────────┐
│SELECT DISTINCT ON ("k") "k","c","s"                                        │
│    FROM (VALUES ('g',1,'a'),('g',2,'b'),('g',NULL,'c')) AS "t"("k","c","s")│
│    ORDER BY "k"         ASC,                                               │
│             "c" IS NULL ASC,                                               │
│             "c"         DESC;                                     →(g,2,b)│
└──────────────────────────────────────┘

つまり、最後のORDERだけ逆(ASC←→DESC)にすればよいだけ。
ちなみに、「"k" ASC」は疑似「GROUP BY」なので、「"k" DESC」でもOK。
ついでに「"c" IS NULL ASC」は「"c" IS NOT NULL ASC」か「"c" IS NULL DESC」に
すれば、NULLが先頭にくる。
分類:PostgreSQL
PostgreSQL/NULLの処遇のおさらい
2013年02月01日
レコード上にNULLが混じっていた場合どうなるのか、
以下のサンプルデータを元におさらいしてみよう。
┌──────────────────────────────────────┐
│SELECT "c" FROM (VALUES (1),(2),(NULL)) AS "t"("c");            →1、2、NULL│
└──────────────────────────────────────┘

まずは、集合関数について。
┌──────────────────────────────────────┐
│SELECT COUNT("c") FROM (VALUES (1),(2),(NULL)) AS t("c");                →2│
│SELECT MAX("c")   FROM (VALUES (1),(2),(NULL)) AS t("c");                →2│
│SELECT MIN("c")   FROM (VALUES (1),(2),(NULL)) AS t("c");                →1│
│SELECT AVG("c")   FROM (VALUES (1),(2),(NULL)) AS t("c");              →1.5│
└──────────────────────────────────────┘
NULLはガン無視されるということだね。

次は並び順について。
┌──────────────────────────────────────┐
│SELECT "c"                                                                  │
│    FROM (VALUES (1),(2),(NULL)) AS "t"("c")                                │
│    ORDER BY "c" ASC;                                           →1、2、NULL│
│SELECT "c"                                                                  │
│    FROM (VALUES (1),(2),(NULL)) AS "t"("c")                                │
│    ORDER BY "c" DESC;                                          →NULL、2、1│
└──────────────────────────────────────┘
ただし、現状はこうですよって感じで、この順は保証されてないっぽい。

ま、動いてんだから…ってのはよくないですよね。
じゃ、NULLを厳密に管理するには?
┌──────────────────────────────────────┐
│SELECT "c"                                                                  │
│    FROM (VALUES (1),(2),(NULL)) AS "t"("c")                                │
│    ORDER BY "c" IS NULL ASC,                                               │
│             "c"         ASC;                                   →1、2、NULL│
│SELECT "c"                                                                  │
│    FROM (VALUES (1),(2),(NULL)) AS "t"("c")                                │
│    ORDER BY "c" IS NULL DESC,                                              │
│             "c" DESC;                                          →NULL、2、1│
└──────────────────────────────────────┘
並び順に「IS NULL」をつけてやればよい。
分類:PostgreSQL
前へ 1 2 3 次へ