2016-04-26 15 views
3

私はOracleには新しく、値に基づいて複数のカウントを含むことを望みます。たとえば、次のように明らかに存在し、カウント(f.id)を有するグループ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; 

は各2回は同じ結果が得られますが、欲望が食べられる食品の種類ごとに1つのカウントを持つことです。りんごとオレンジ。結果は次のようになります。

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

つまり、結果ごとに複数のカウントがあります。この場合、人が食べた食べ物の数。

私のクエリでは、名前ごとに2つの結果が返されます。つまり、となりますが、SQL結果から名前ごとに結果が1つ必要です。

答えて

2

Oracleのようにグループ化するのは習慣的ではありませんが、必要な場合でも可能です。代わりに、より良い習慣と私の提案は、nameidの両方でグループ化して、果実ごとに1つずつ2つの行を生成することです。

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が存在し、もう一方の解決策がその1つを試行します。私の好みの方法は、この目的のために特別に導入された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

おかげで、私は今、二列にそれらを得ることができますが、アプリケーションは非常に良い仕事です1つの場合は完了です。私は、それがあまりにも複雑すぎると思っています。 – LookingToLearn

+0

@lookingtolearn、私は私の答えに働くソリューションを追加しましたが、アプリケーションがもっとうまくいくかどうかはわかりません。消費するアプリケーションが期待する結果を得るには、良いdbモデルをピボットまたはトランスポーズする必要はありません。 – 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で直接実行してみることはできますか? –

関連する問題