sql >> データベース >  >> RDS >> PostgreSQL

条件でエイリアスcoalesceを使用する:coalesce(max(case when value then value)asエイリアス

    コメントのディスカッションごとに、各ad_idを期待しているため ad_paramsで 単一のvalueを持つ nameごと 、コードを次のように書き直して、必要なフィルターを簡単に追加できます:

    select ad_media.ad_media_id
    , ad_media.ad_id
    , ads.name
    , action_states.timestamp
    , regdate.value AS regdate
    , mileage.value AS mileage
    , fuel.value AS fuel
    , brand.value AS brand
    , model.value AS model
    
    from ad_media 
    inner join action_states 
        on action_states.ad_id = ad_media.ad_id
    inner join ads 
        on ads.ad_id = action_states.ad_id
    left join ad_params as regdate --technically we could do an inner join here since we're using this in the WHERE clause now; but I'll leave as an outer join in case you need more advanced logic...
        on regdate.ad_id = ad_media.ad_id
        and regdate.name = 'regdate' 
    left join ad_params as mileage
        on mileage.ad_id = ad_media.ad_id
        and mileage.name = 'mileage' 
    left join ad_params as fuel
        on fuel.ad_id = ad_media.ad_id
        and fuel.name = 'fuel' 
    left join ad_params as brand
        on brand.ad_id = ad_media.ad_id
        and brand.name = 'brand' 
    left join ad_params as model
        on model.ad_id = ad_media.ad_id
        and model.name = 'model' 
    
    where action_states.state = 'reg'   
    and action_states.action_id = '1' 
    and action_states.timestamp::DATE BETWEEN '2018-04-17' AND '2018-04-17'
    and ads.category = '2010'   
    and regdate.value = '2018' --your condition 
    
    /* --this is probably no longer needed; if it is instead consider adding a `distinct`
    group by ad_media.ad_media_id
    , ad_media.ad_id
    , ads.name
    , action_states.timestamp 
    order by ad_media.ad_id;
    */
    

    元のSQLに合わせてさらに何かが必要な場合は、以下も機能します。

    select ad_media.ad_media_id
    , ad_media.ad_id
    , ads.name
    , action_states.timestamp
    , max(CASE WHEN ad_params.name = 'regdate' THEN ad_params.value END) AS regdate
    , max(CASE WHEN ad_params.name = 'mileage' THEN ad_params.value END) AS mileage
    , max(CASE WHEN ad_params.name = 'fuel'    THEN ad_params.value END) AS fuel
    , max(CASE WHEN ad_params.name = 'brand'   THEN ad_params.value END) AS brand
    , max(CASE WHEN ad_params.name = 'model'   THEN ad_params.value END) AS model
    
    from ad_media 
    left join action_states 
        on action_states.ad_id = ad_media.ad_id
    inner join ads 
        on ads.ad_id = action_states.ad_id
    inner join ad_params --since we expect this filter to remove results, we now need it to be an inner join
        ad_params.ad_id = on ad_media.ad_id
        and 
        (
            ad_params.name != 'regdate' --\_i.e. if the value is regdate we want 2018; if it's not regdate we'll take any value
            or ad_params.value = '2018' --/
        )
    
    where action_states.state = 'reg'   
    and action_states.action_id = '1' 
    and action_states.timestamp::DATE BETWEEN '2018-04-17' AND '2018-04-17'
    and ads.category = '2010'   
    
    group by ad_media.ad_media_id
    , ad_media.ad_id
    , ads.name
    , action_states.timestamp 
    order by ad_media.ad_id;
    

    これは他の多くの方法でも書き直すことができます。ただし、bsetを選択するには、スキーマとデータについて詳しく知る必要があります。この投稿では、役立つ関連情報を少し紹介しています: https://stackoverflow.com/a/7449213/361842 (ただし、PostgresではなくMSSQLに焦点を当てていますが、同様のアイデアが適用されます)。




    1. 特定の条件に基づくmysqlエクスポートテーブル

    2. SQL Server(T-SQL)で文字列の正しい部分を取得する

    3. SQLストアドプロシージャのパラメータが破損していますか?

    4. 行の最初の空の列にSQLを挿入するMySQLエラー