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

chuuken kenkou ken_ken_1962 @ hotmail.com
2007年 8月 22日 (水) 04:06:06 JST


忠犬です。

少し勘違いがありました。

前回のメールのSQLでは、以下を見逃してしまいました。

(1)「''」(長さ=0の文字列)も、Oracleのようにnullと同じ値として並べたい
(2)c2,c1の優先度でソートするが、(1)はそれに優先する

質問者さんのSQLは、「c3をnullの区別とともに、c2の値も入れてc3で
ソートする」という考えでしたが、c3はnullの区別だけに使い、c2の値は
c2を直接見るようにすれば解決できると思います。

<SQL例>
1.c3も表示していい場合

SELECT 
  c1, 
  c2, 
  CASE 
    WHEN c2 IS NULL OR TRIM(c2) = '' THEN 2
    ELSE 1
  END  AS c3
FROM t1
ORDER BY c3, c2, c1;

2.c3は表示したくない場合

SELECT 
  c1, 
  c2
FROM t1
ORDER BY 
  CASE 
    WHEN c2 IS NULL OR TRIM(c2) = '' THEN 2
    ELSE 1
  END,
  c2, c1;


>忠犬です。
>
>>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/
>

_________________________________________________________________
夏のレジャーに便利な花火大会マップや全国水族館マップはこちら 
http://chizumaga.jp/ 




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