我有4张桌子。 table1有一列名为reportable_type,另一列名为reportable_id。 reportable类型有两个值,table2或table3。 table2和table3都有一个table4_id列。我正在尝试编写一个查询,在一个结果中获取table1.id和table4.description。感觉就像postgres的案例陈述会让我在那里,但我迷路了,也有两个案例陈述可能打破了这个:
select t1.id, t4.description
from table1 as t1
case
when t1.reportable_type = ’table2’
then left join table2 as t2 on t1.reportable_id = t2.id
else left join table3 as t3 on t1.reportable_id = t3.id
end
left join table4 as t4 on
case
when t1.reportable_type = ’table2’
then t2.table4_id =t4.id
else t3.table4_id =t4.id
end
group by t4.description;
编辑:
想要围绕这个添加一些数据,这样更清楚。
让我们使用以下数据:
table 1
IDs - 1, 2
reportable_type - table 2, table 3
reportable_id - 1, 1
table 2:
id - 1
t4_id - 1
table 3:
id - 1
t4_id - 2
table 4:
id - 1 ,2
description - first, second
因此查询的结果表应为:
id - 1,2
description - first, second
答案 0 :(得分:3)
我们必须在t2和t3上保持联接,因为t1.reportable_Type不能是<> 'table2'和= table2。然后我们可以从T3,t2中的任一ID coalesce
{t}与t4的关系值。
这确实意味着左边连接都必须尝试解析,因此它可能不如试图找出如何只执行其中一个左连接那样高效。但结果应该准确。一旦你开始工作,如果性能是一个问题,我们需要查看执行计划/索引,看看是否有另一种方法来优化它。
SELECT t1.id, t4.description
FROM table1 as t1
LEFT join table2 as t2
on t1.reportable_id = t2.id
and t1.reportable_type = 'table2'
LEFT join table3 as t3
on t1.reportable_id = t3.id
and coalesce(t1.reportable_type,'isNull') <> 'table2'
LEFT join table4 as t4
on t4.id = coalesce(t2.table4_id, t3.table4_ID)
--GROUP BY t4.description;
不确定为什么你有一个没有聚合的小组。所以我评论出来;也许你的意思是ORDER BY
;我通常认为在几乎所有查询中都包含订单是明智的;特别是那些可以使用索引的那些。
如果t1.reportable_type为null,我还添加了and coalesce(t1.reportable_type,'isNull') <> 'table2'
来使用coalesce来处理这种情况。我假设您仍然希望那些记录为null的记录不等于'table2',但您可能根本不想要那些记录;所以我们需要有关该特定案例的更多信息。
&lt;&gt;因为我不相信可以使用索引,所以t3上的连接条件也可能有点性能。但是我不知道如何解决这个问题,但也许是in或者存在,子查询会起作用......但我会让你从这里开始玩。