Na diskuzi v komentářích, protože očekáváte každé ad_id
v ad_params
mít jednu value
podle name
, můžeme přepsat váš kód, jak je uvedeno níže, a snadno přidat požadovaný filtr:
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;
*/
Pokud chcete něco více v souladu s vaším původním SQL, níže by také fungovalo:
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;
Můžeme to přepsat i mnoha jinými způsoby; ale abychom si vybrali bset, potřebovali bychom vědět více o vašem schématu a datech. Tento příspěvek poskytuje trochu užitečných souvisejících informací:https://stackoverflow.com/a/7449213/361842 (i když se zaměřuje spíše na MSSQL než na Postgres; ale podobné myšlenky platí).