category 表中的四个类别。
id | name
--------------
1 | 'wine'
2 | 'chocolate'
3 | 'autos'
4 | 'real estate'
forecaster 表中众多(数千名)预报员中的两位。
id | name
--------------
1 | 'sothebys'
2 | 'cramer'
预报员对预测表中类别的相关预测。
| id | forecaster_id | category_id | forecast |
|----+---------------+-------------+--------------------------------------------------------------|
| 1 | 1 | 1 | 'bad weather, prices rise short-term' |
| 2 | 1 | 2 | 'cocoa bean surplus, prices drop' |
| 3 | 1 | 3 | 'we dont deal with autos - no idea' |
| 4 | 2 | 2 | 'sell, sell, sell' |
| 5 | 2 | 3 | 'demand for cocoa will skyrocket - prices up - buy, buy buy' |
我想要(预测,类别,预测)的优先级映射,以便在某些主要预测者存在预测时(例如' cramer& #39; )使用它因为我更信任他。如果某些辅助预测者(例如' sothebys' )存在预测,请使用该预测。如果某个类别没有预测,请返回包含该类别的行,并返回null
进行预测。
我有一些几乎可以工作的东西,在我得到逻辑后,我希望变成参数化查询。
select
case when F1.category is not null
then (F1.forecaster, F1.category, F1.forecast)
when F2.category is not null
then (F2.forecaster, F2.category, F2.forecast)
else (null, C.category, null)
end
from
(
select
FR.name as forecaster,
C.id as cid,
C.category as category,
F.forecast
from
forecast F
inner join forecaster FR on (F.forecaster_id = FR.id)
inner join category C on (C.id = F.category_id)
where FR.name = 'cramer'
) F1
right join (
select
FR.name as forecaster,
C.id as cid,
C.category as category,
F.forecast
from
forecast F
inner join forecaster FR on (F.forecaster_id = FR.id)
inner join category C on (C.id = F.category_id)
where FR.name = 'sothebys'
) F2 on (F1.cid = F2.cid)
full outer join category C on (C.id = F2.cid);
这给出了:
'(sothebys,wine,"bad weather, prices rise short-term")'
'(cramer,chocolate,"sell, sell, sell")'
'(cramer,autos,"demand for cocoa will skyrocket - prices up - buy, buy buy")'
'(,"real estate",)'
虽然这是所需数据,但它是一列而不是三列的记录。 case
是我能够找到的唯一方法,可以实现cramer
下一个sothebys
的排序,并且有很多重复。有没有更好的方法,如何将元组结果拉回到列中?
任何建议,特别是与删除重复或一般简化有关的建议表示赞赏。
答案 0 :(得分:2)
这听起来像是DISTINCT ON
(未经测试)的情况:
SELECT DISTINCT ON (c.id)
fr.name AS forecaster,
c.name AS category,
f.forecast
FROM forecast f
JOIN forecaster fr ON f.forecaster_id = fr.id
RIGHT JOIN category c ON f.category_id = c.id
ORDER BY
c.id,
CASE WHEN fr.name = 'cramer' THEN 0
WHEN fr.name = 'sothebys' THEN 1
ELSE 2
END;
对于每个类别,将选择订购中的第一行。由于Cramer比苏富比的id
更高,因此会优先考虑。
如果您需要更复杂的排名,请调整ORDER BY
子句。