[pgsql-jp: 38672] Re: SELECT文、NULL やスペースを含む列でのソートについて

���� KEN ken_ken_1962 @ hotmail.com
2007年 8月 22日 (水) 03:01:33 JST


忠犬です。

>NULL のデータを含む列の昇順で、データを並べたいのですが、
>値がNULL のデータは最後に並んで欲しいのです。
>     -------------------------------------------------------
>     SELECT
>       c1,
>       c2,
>       CASE
>         WHEN c2 IS NULL OR TRIM(c2) = '' THEN 'ZZZZ'
>         ELSE c2
>       END  AS c3
>     FROM t1
>     ORDER BY c3, c1;
>     -------------------------------------------------------
>という書き方では、c2 列に全角の文字列が入るとたちまち
>具合悪いですので、max_value なんてのがあればと探してみましたが、
>見つかりません。

c2がnullかnull以外かだけ区別すればいいのに、余計なことを行っている
のが問題です。

  CASE 
   WHEN c2 IS NULL THEN 2
   ELSE 1
  END AS c3 

とすればいいだけではないでしょうか?

>※Oralce の nvl() や、SQL Serverのisnull() に相当する関数も
>   見つかりません。

PostgreSQLを含め、多くのRDBMSで実装されている「coalesce(式1,式2)」で
代用できるのでは?

>>-- 3a. Oracleとは違って、'' と NULL は区別される。

多くのRDBMS(標準SQLも?)は、「長さ0の文字」とnullは、別の値として扱いま
す。
同じ値として扱うOracleの方が、特異なのです。

c3を表示してもいいなら、次のSQLで希望の結果を得られると思います。

SELECT 
  c1, 
  c2,
  CASE 
   WHEN c2 IS NULL THEN 2
   ELSE 1
  END AS C3 
FROM t1
ORDER BY c3, c1;

c3を表示したくないなら、次のSQLで希望の結果を得られると思います。

SELECT 
  c1, 
  c2
FROM t1
ORDER BY 
  CASE 
   WHEN c2 IS NULL THEN 2
   ELSE 1
  END,
  c1; 




>■以下、動作確認を行った時の SQL文です。
>
>-- 1. テスト用テーブル作成
>DROP TABLE IF EXISTS t1 ;
>CREATE TABLE t1 (
>   c1  VARCHAR(2)   PRIMARY KEY,
>   c2  VARCHAR(10)
>);
>-- 2. テスト用データ作成
>INSERT INTO t1 VALUES ('01', NULL);
>INSERT INTO t1 VALUES ('02', NULL);
>
>INSERT INTO t1 VALUES ('11', 'AAAAAAAAAA');
>INSERT INTO t1 VALUES ('12', 'BBBBBBBBBB');
>INSERT INTO t1 VALUES ('13', 'CCCCCCCCCC');
>INSERT INTO t1 VALUES ('14', 'DDDDDDDDDD');
>INSERT INTO t1 VALUES ('15', 'EEEEEEEEEE');
>
>INSERT INTO t1 VALUES ('21', '');
>INSERT INTO t1 VALUES ('22', '');
>
>INSERT INTO t1 VALUES ('23', '全角文字');
>
>-- 3. 検索
>SELECT * FROM t1;
>-- 3a. Oracleとは違って、'' と NULL は区別される。
>SELECT * FROM t1 WHERE c2 IS NULL;   -- 01, 02
>SELECT * FROM t1 WHERE c2 = '';      -- 21, 22
>SELECT * FROM t1 WHERE TRIM(c2) = '';      -- 21, 22
>
>-- 3b. NULLの項目を含む列で昇順にソートする時、どう記述すべきか不明。
>--     以下では、全角文字が入るとたちまち具合悪い。。。
>SELECT
>   c1,
>   c2,
>   CASE
>     WHEN c2 IS NULL OR TRIM(c2) = '' THEN 'ZZZZ'
>     ELSE c2
>   END  AS c3
>FROM t1
>ORDER BY c3, c1;

_________________________________________________________________
インターネットを見るなら最新のMSN版IE7で!ダウンロード無料 
http://promotion.msn.co.jp/ie7/ 




pgsql-jp メーリングリストの案内