我为表ad_params
提供了交叉表,所以我做了:
coalesce(max(CASE when ad_params.name='model' and ad_params.value='cordova'then ad_params.value end ),NULL)
要修复它,但条件是ad_params.value='cordova'
无效
它会在model
为cordova
时显示所有结果,只显示model
字段中的空白,因此我必须删除所有不在其中的字段
************************************************************************
ad_media_id | ad_id | name | timestamp| regdate | brand | fuel |model
xxxxxxxxxxx 1 jack xxxx cordova
xxxxxxxxxxx 2 joe xxxx cordova
************************************************************************
所以我必须拥有1号
coalesce(max(CASE WHEN ad_params.name='regdate'
THEN ad_params.value END),NULL) AS regdate,
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
on ad_params.ad_id = ad_media.ad_id
and
(
ad_params.name = 'model'
and ad_params.value = 'cordoba'
)
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;
答案 0 :(得分:0)
在评论中进行讨论,因为您希望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(虽然专注于MSSQL而不是Postgres;但类似的想法适用)。