2016-04-26 88 views
3

我是Oracle的新手,希望结果包含基于值的多个计数。例如:每个结果合并Group BY和多个计数

SELECT p.name, count(f.id) as eaten_apples, count(f.id) as eaten_oranges 
FROM food f, people p 
WHERE f.pid=p.pid 
AND f.id = 'apple' OR f.id = 'orange' 
GROUP BY p.name; 

显然具有计数(f.id)有两次将各自产生相同的结果,但愿望是具有每吃的食物的类型的一个计数。苹果和橘子。预期结果可能如下所示:

[0] => 
    name : john 
    eaten_apples: 3 
    eaten_oranges: 1 
[1] => 
    name : sam 
    eaten_apples: 0 
    eaten_oranges: 9 
... 

换句话说,每个结果有多个计数。在这种情况下,一个人吃的食物数量。

我的查询现在返回两个每个名称的结果,我可能在SQL之外组合,但我想从SQL结果每个名称得到一个结果。

回答

2

在Oracle中这样分组并不习惯,但如果需要的话,它仍然是可能的。相反,更好的做法和我的建议是由nameid产生两行,每个水果一行。

SELECT p.name, f.id, count(1) as eaten_fruit 
from food f, people p 
WHERE f.pid=p.pid 
AND (
     f.id = 'apple' OR 
     f.id = 'orange' 
    ) 
GROUP BY p.name, f.id; 

我相信,让数据的应用程序句柄阅读上面是更有效的,但正如我指出的那样,有重新格式化选项。有a number of ways to transpose these row based results into columns和其他解决方案尝试其中之一。我偏好的方法是使用专门为此目的而引入的PIVOT operator。为了得到结果,你想要的格式,你可以移调行转换成列如:

select name, id from 
        (
         select p.name, f.id 
         from food f, people p 
         where f.pid = p.pid 
         and f.id in ('apple','orange') 
        ) 
pivot (
      count(id) 
      for id in (
         'apple' as eaten_apples, 
         'orange' as eaten_oranges 
        ) 
    ); 

它会工作,但不常见。

+0

谢谢,但我可以在两排让他们了,但应用程序将运行得更好如果在一个完成。我认为在Oracle中执行起来太复杂了,或者更慢? – LookingToLearn

+0

@lookingtolearn,我添加到我的答案一个工作解决方案,但我不知道如果应用程序会更好。一个好的数据库模型不应该为了获得消费应用程序期望的结果而进行透视或转置。 – Spade

+0

谢谢!我结束了与ORA-00904:“id”:无效的标识符。但是,将“select name,id”更改为“select *”使其起作用。我不知道为什么,但最终通过广泛的反复试验获得了他们的结果。再次,谢谢! – LookingToLearn

0

这里是一个选择,这将给在一个记录每人吃苹果和桔子的数量:

WITH cte AS 
(
    SELECT p.name, f.id 
    FROM people p LEFT JOIN food f 
     ON f.pid = p.pid 
) 

SELECT t1.name, COALESCE(t1.aCount, 0) AS eaten_apples, 
    COALESCE(t2.oCount, 0) AS eaten_oranges 
FROM people AS p 
LEFT JOIN 
(
    SELECT name, COUNT(name) AS aCount 
    FROM cte 
    WHERE id = 'apple' 
    GROUP BY name 
) AS t1 
    ON p.name = t1.name 
LEFT JOIN 
(
    SELECT name, COUNT(name) AS oCount 
    FROM cte 
    WHERE id = 'orange' 
    GROUP BY name 
) AS t2 
    ON p.name = t2.name 
+0

谢谢,但我一定在做错事。你能明白为什么我会得到“ORA-00933:SQL命令未正确结束”吗?我正在通过PHP执行。 – LookingToLearn

+0

没有看到你的代码,这将很难调试。你能尝试直接在你的Oracle中运行这个查询吗? –