2017-06-24 6 views
0

bookまたはmovieのいずれかに設定された_typeという列の、selected_mediaという名前のpostgres 9.6テーブルがあります。私は、各タイプのCOUNTを選択したいPG:結果が0の場合、このクエリの合計数を表示するには

は、1つの行に、次のように:

25 | 715

これを行うために、私はこのクエリを持っている:

SELECT 
    COALESCE(SUM(CASE WHEN _type = 'book' THEN 1 ELSE 0 END), 0) AS books_count, 
    COALESCE(SUM(CASE WHEN _type = 'movie' THEN 1 ELSE 0 END), 0) AS movies_count 
FROM selected_media 
WHERE subscriber_id = $1 

問題があります2倍:

  1. 各列にrespec その_typeの合計数はで、その列の合計が0(選択されていない)の場合にのみ発生します。これは、UI/UXの状態がであるため、「書籍または映画を0で選択することは、すべてを選択することと同じです」です。

    SELECT 
    COUNT(*) FILTER (WHERE _type = 'book') AS books_count, 
    COUNT(*) FILTER (WHERE _type = 'movie') AS movies_count 
    FROM selected_media 
    WHERE subscriber_id = $1; 
    

    詳細情報here:それは高速であることが必要

  2. 、この表には、あなたがFILTER句でCOUNTを使用することができます

答えて

1

それに数百万行を持つことになります。


EDIT

あなたの最初の必要性を達成するために、ネストされたサブクエリを使用します。

SELECT 
    CASE books_count WHEN 0 THEN (SELECT COUNT(*) FROM selected_media WHERE _TYPE = 'book') ELSE books_count END AS books_count_final, 
    CASE movies_count WHEN 0 THEN (SELECT COUNT(*) FROM selected_media WHERE _TYPE = 'movie') ELSE movies_count END AS movies_count_final 
FROM 
    (
    SELECT 
     COUNT(*) FILTER (WHERE _type = 'book') AS books_count, 
     COUNT(*) FILTER (WHERE _type = 'movie') AS movies_count 
    FROM 
     selected_media 
    WHERE 
     subscriber_id = $1 
    ) AS sub_query 

CTEを使用して:ところで

WITH selected_media_sub AS (
    SELECT 
     COUNT(*) FILTER (WHERE _type = 'book') AS books_count, 
     COUNT(*) FILTER (WHERE _type = 'movie') AS movies_count 
    FROM 
     selected_media 
    WHERE 
     subscriber_id = $1 
) 

SELECT 
    CASE books_count WHEN 0 THEN (SELECT COUNT(*) FROM selected_media WHERE _TYPE = 'book') ELSE books_count END AS books_count_final, 
    CASE movies_count WHEN 0 THEN (SELECT COUNT(*) FROM selected_media WHERE _TYPE = 'movie') ELSE movies_count END AS movies_count_final 
FROM selected_media_sub; 

、あなただけの非ゼロカウントが必要な場合次の操作を行うことができます:

SELECT 
    COALESCE(NULLIF(COUNT(*) FILTER (WHERE _type = 'book'), 0), 1) AS books_count, 
    COALESCE(NULLIF(COUNT(*) FILTER (WHERE _type = 'movie'), 0), 1) AS movies_count 
FROM 
    selected_media 
WHERE 
    subscriber_id = $1 
+0

これは、私が持っていたものの偉大なリファクタリングです(ありがとう!)、しかしそれはまだ私が必要とするポイント#1をしません。 – Tallboy

+0

私はあなたが必要とするものに少し混乱しています。タイプごとのカウントが0であるとしましょう。したがって、全体のカウントが必要ですか? –

+0

修正。カウントが0以上であればフィルタリングする必要がありますが、0なら単にCOUNT(*)をselected_media WHERE _type = 'x''から選択するだけです(ただし、複数のカウントを組み合わせるなど) – Tallboy

関連する問題