2017-01-04 12 views
0

私はいくつかのディストリビュータを持つフィーダを持つデータベースを持っています。各フィーダにはいくつかのトランスと、複数のクライアントと、特定のkVA(クライアントへの電力) 。和は変圧器が持つさまざまなkVAの和を持って来ることになっている同じ値を持つ 'distinct'行を合計する

SELECT f.feeder, 
    d.distributor, 
    count(DISTINCT t.transformer) AS total_transformers, 
    sum(t.Kvan) AS Total_KVA, 
    count(c.client) AS Clients, 
FROM feeders f 
    LEFT JOIN distributors d 
     ON (d.feeder = f.feeder) 
    LEFT JOIN transformers t 
     ON (t.transformer = d.transformer) 
    LEFT JOIN clients c 
     ON (c.transformer = t.transformer) 
WHERE d.transformer IS NOT NULL 
GROUP BY f.feeder, 
    d.distributor, 
    f.feeder 
ORDER BY f.feeder, 
    d.distributor 

: は、私は次のコードを持っています。各変圧器には一定のkVAがあります。問題は、接続されているすべてのクライアントに対して1つの変圧器が1kVAを持っていますが、クライアントあたり1kVAのように合計します。 フィーダとディストリビューターにグループ分けする必要があります(ディストリビューターにはどれくらいのkVAがあり、どのくらいの数のクライアントが集まっているのか見たいと思っています)。 "feeder1 | dist1 | 2 | 600 | 374"にすると、 "feeder1 | dist1 | 2 | 130000 | 374"(1トランスに200 kVA、もう1つに400がありますが、 400 + 200)

+5

質問の書式を設定し、関連するRDBMSにタグを付け、サンプルデータと予想される出力を追加します。 – sagi

+1

あなたの 'Where'句は' Left Join'を 'Inner Join'に変換しました。そして重要なことではなく、「フィーダー」で2回グループ化する必要はありません。 –

+0

**あなたの質問を編集し、そのデータに基づいてサンプルデータと予想される出力を追加してください。 [**フォーマットされたテキスト**](http://stackoverflow.com/help/formatting)、[スクリーンショットなし](http://meta.stackoverflow.com/questions/285551/why-may-i-not -upload-images-of-code-on-so-asking-a-question/285557#285557) –

答えて

0

あなたのデータモデルは、ディストリビューターが多くのトランスを持つことができます(そして、ロジックはトランスフォーマーが1つのディストリビューターのみであることを示唆しています)通常は反対の関係を意味するディストリビューターレコードにあります。

したがって、同じディストリビューターのディストリビューターテーブルに複数のレコードがあることを意味する必要があります。つまり、ディストリビューターは一意ではありませんディストリビューターのテーブルのキーを押して、クエリを正確に推論することを非常に困難にします約。 (例えば、ディストリビューターのレコードがすべて同じフィーダーIDを持っていない場合はどうなりますか?答えがあまり好きではないと思います...おそらくそれは不可能であることを意味しますが、他のテーブルの見た目のキーが実際にはユニークであるかどうかを2番目に推測しています...しかし、私は逃げます...)

多分、何かが壊れています。ポイントはあなたが与えた情報が不一致か不完全かもしれないということです。私が異常なデータモデルを推測しているので、以下はバグがないことを保証することはできません(私は推測を減らすために詳細を述べると答えが洗練されるかもしれません)...

ですから、集約を行う準備が整う頃には、変圧器のデータは、変圧器のアイデンティティだけに基づいていない大きな行に埋め込まれてしまうという問題があります。あなたがそれを修正できるいくつかの方法があります。基本的には、すべての値の集計方法を変更することが中心です。ここでは一つの選択肢です:

select f.feeder 
    , dtc.distributor 
     -- next values work because transformer is already unique per group 
    , count(dtc.transformer) total_transformers 
    , sum(dtc.kvam) total_kvam 
    , sum(dtc.clients) clients 
    from  feeder f 
     join (select d.distributor 
        , d.feeder 
        , t.transformer 
        , max(t.kvan) as kvan -- or min, doesn't matter 
        , count(distinct c.client) clients 
       from   distributors d 
        left join transformers t 
          on d.transformer = t.transformer 
        left join clients c 
          on c.transformer = t.transformer 
       where d.transformer is not null 
       group by d.distributor, d.feeder, t.transformer 
      ) dtc 
     on dtc.feeder = f.feeder 
group by f.feeder, dtc.distributor 

いくつかの注意事項:

オリジナルの左から任意のヌル行がfeederから参加するので、私は、外側のクエリが参加し、内側に参加する変更は、元のwhere句によって排除されるだろう。

とにかくwhere句を保持しました。 distributor -to-transformer左結合はちょっと変わっていますが、where節がなくても内部結合または外部結合とは異なります(where句は左テーブルの値に作用するため)。私は元のクエリからセマンティクスを変更することは避けていますが、これは別の見方をしたいと思うかもしれない何かが不思議です。

内部クエリは、フィーダ/ディストリビュータ/トランスフォーマごとに1つのローを返します。つまり、各フィーダ/ディストリビュータに対して、トランスあたり1つのローを返します。その行はそれ自体が集合体なので、クライアントを数えることができますが、その集約のすべての行は同じトランスレコードから来ているので、max()を使用してその単一レコードのkvan値を集計に取り入れることができます。

関連する問題