2017-02-13 18 views
1

ブール型フラグを含むレコードを取得しようとしています。特定の結果セットのカラムに少なくとも1つのNOT NULL値がある場合はtrue、すべての値がNULLの場合はfalseです。結果のNULL/NOT NULLフラグを最適化PostgreSQLクエリ

サンプルデータがある必要があり、この場合、結果は

SELECT "my column 1", "my column 2", "my column 3", "my column 4", "my column 5" 
FROM my_data 
WHERE date BETWEEN :start AND :end 

"my column 1" "my column 2" "my column 3" "my column 4" "my column 5" 
    NULL   NULL   25.2   NULL   1.12 
    15.28   NULL   NULL   NULL   2.25 
    NULL   NULL   13.9   NULL   3.03 
    359.00  NULL   125.5   NULL   4.15 
    NULL   NULL   152.2   NULL   5.99 
    NULL   NULL   NULL   NULL   6.35 

を設定します。

"my column 1" "my column 2" "my column 3" "my column 4" "my column 5" 
    t    f    t    f    t 

次PostgreSQLのクエリん私は実際にそれが最初とすぐに、各サブクエリを終了する(必要な正確に何NOT NULL値が検出されました)、最適化することはできますか?:

WITH x AS (SELECT * FROM my_data WHERE date BETWEEN :start AND :end) 

SELECT 
    EXISTS(SELECT * FROM x WHERE "my column 1" IS NOT NULL) AS "my column 1", 
    EXISTS(SELECT * FROM x WHERE "my column 2" IS NOT NULL) AS "my column 2", 
    EXISTS(SELECT * FROM x WHERE "my column 3" IS NOT NULL) AS "my column 3", 
    EXISTS(SELECT * FROM x WHERE "my column 4" IS NOT NULL) AS "my column 4", 
    EXISTS(SELECT * FROM x WHERE "my column 5" IS NOT NULL) AS "my column 5" 

私は、各列の名前を言及することなく、短くまたは全般的に書くことができると思った。

+0

それは打撃性能ですか? –

+0

CASEを使用できますか? https://www.postgresql.org/docs/9.4/static/functions-conditional.html – lionbtt

+0

@Ranadip Dutta:いいえ、しかし、私は、各列名に言及することなく、短くても普遍的にでも書くことができると思いました。 – Paul

答えて

6

別の代替

CASE WHEN "my column 1" IS NULL THEN 0 ELSE 1 END 

このNOT NULL列数を追加bool_or()を使用することですaggregate - 少なくとも1つの値がtrueの場合にtrueを返します。

SELECT bool_or("my column 1" is not null) AS "my column 1", 
     bool_or("my column 2" is not null) AS "my column 2", 
     bool_or("my column 3" is not null) AS "my column 3", 
     bool_or("my column 4" is not null) AS "my column 4", 
     bool_or("my column 5" is not null) AS "my column 5" 
FROM my_data 
WHERE date BETWEEN :start AND :end; 

すべての値がtrueの場合にのみtrueを返しますbool_and()集計もあります。

+0

さて、 'bool_or'は最適化されているようです。その名前は、最初の 'true'値が見つかったときに集約を停止することを約束します。そうでないかもしれません。 – Paul

1

NOT NULL列に対して、このリターン1:

COUNT(<previous case>) > 0 

最終クエリ:

SELECT CASE 
      WHEN COUNT(CASE WHEN "my column 1" IS NULL THEN 0 ELSE 1 END) > 0 
      THEN true 
      ELSE false 
     END, 
     -- ..... same for the other columns 
     -- , "my column 2", "my column 3", "my column 4", "my column 5" 
FROM my_data 
WHERE date BETWEEN :start AND :end 
+0

@a_horse_with_no_nameはい、私はローレンツの答えを見ました。 :$ –

4
SELECT 
    count("my column 1") > 0 AS "my column 1", 
    count("my column 2") > 0 AS "my column 2", 
    count("my column 3") > 0 AS "my column 3", 
    count("my column 4") > 0 AS "my column 4", 
    count("my column 5") > 0 AS "my column 5" 
FROM my_data 
WHERE date BETWEEN :start AND :end;