2016-08-24 52 views
1

我在Postgres上执行了查询,并使用了Postgres 9.4或更高版本中提供的FILTER子句,但我被告知只能使用标准SQL子句。在Postgres上更改查询以仅使用标准SQL子句

我的查询是如何计算有多少动物被屠宰,屠宰动物的数量将被显示为每个企业和动物类型:

Enterprise(id or name) || cow || sheep || chicken 
MacDonals    || 5 || 5 || 1  
Burguer King   || 7 || 4 || 2  
KFC     || 1 || 0 || 10  

所以我在POSTGRES 9.4使这个原生查询:

SELECT e.name 
,COALESCE (COUNT(a.id) FILTER (WHERE a.type='cow')) 
,COALESCE (COUNT(a.id) FILTER (WHERE a.type='sheep')) 
,COALESCE (COUNT(a.id) FILTER (WHERE a.type='chicken')) 
FROM enterprise e 
INNER JOIN animal_enterprise ae 
ON (ae.enterprise_id = e.id) 
INNER JOIN animal a 
ON (ae.animal_id=a.id) 
GROUP BY e.id 

所以,我试过对每种类型的动物做子查询,但它不如它应该好。

+1

这已经是标准的SQL –

+0

我认为是相同的,但Filter子句是postgres 9.4或更高版本中的一个新特性,它在mysql中的等价物不能以同样的方式存在或执行。然后,Case子句更适合以标准化方式编写查询。 – ruselli

+0

过滤条款***是*** SQL标准的一部分。当涉及SQL功能或SQL标准时,MySQL几乎不是基准。如果你想要一个在Postgres **和** MySQL上运行的语句,那么你不应该请求一个“标准的SQL”语句。 –

回答

2

如果我理解正确的是如何filter作品,这可以通过使用case表达count函数内部翻译:

SELECT e.name 
    ,COUNT(case when a.type='cow' then 'X' end) as cow 
    ,COUNT(case when a.type='sheep' then 'X' end) as sheep 
    ,COUNT(case when a.type='chicken' then 'X' end) as chicken 
FROM enterprise e 
INNER JOIN animal_enterprise ae 
    ON ae.enterprise_id = e.id 
INNER JOIN animal a 
    ON ae.animal_id = a.id 
GROUP BY e.id, e.name 

我忽略了在查询一些异常现象,如使用的p.id?当没有在别处定义的别名p,或者没有第二个参数时使用​​3210。