2016-07-02 8 views
1

列内の特定の値に対してデータセットの出現の平均を計算する必要があります。私は簡単な例を作りましたが、現在のデータベースでは、100kレコードに減らすために、約2つの内部結合が含まれています。私は10列に対して以下のselect distinct文を実行する必要があります。MYSQL列内の特定の出現の平均を計算する

私の現在のデザインでは、各列に対してインナー結合が強制されます。もう1つの制約は、この例では名前ごとに少なくとも50〜100行を実行する必要があるということです。

クエリを高速化するにはあまりにも多くのリソースを使用せずにこの値を計算する効率的な方法を見つけ出す必要があります。

http://sqlfiddle.com/#!9/c2378/3

私の予想結果は次のとおりです。

Name | R Avg dir | L Avg dir 1 | L Avg dir 2 | L Avg dir 3 
A   0    .5     .25   .25 

は、テーブル、クエリを作成します。

CREATE TABLE demo 
    (`id` int, `name` varchar(10),`hand` varchar(1), `dir` int) 
; 

INSERT INTO demo 
    (`id`, `name`, `hand`, `dir`) 
VALUES 
    (1, 'A', 'L', 1), 
    (2, 'A', 'L', 1), 
    (3, 'A', 'L', 2), 
    (4, 'A', 'L', 3), 
    (5, 'A', 'R', 3), 
    (6, 'A', 'R', 3) 
; 

クエリ例:

SELECT distinct name, 
COALESCE(((Select count(id) as 'cd' from demo where hand = 'L' AND dir = 1) /(Select count(id) as 'fd' from demo where hand = 'L')),0) as 'L AVG dir' 
FROM 
    demo 
    where hand = 'L' AND dir = 1 AND name = 'A' 

答えて

1

一つのオプションは使用することですconditional aggregation

SELECT name, 
     count(case when hand = 'L' and dir = 1 then 1 end)/
      count(case when hand = 'L' then 1 end) L1Avg, 
     count(case when hand = 'L' and dir = 2 then 1 end)/
      count(case when hand = 'L' then 1 end) L2Avg, 
     count(case when hand = 'L' and dir = 3 then 1 end)/
      count(case when hand = 'L' then 1 end) L3Avg, 
     count(case when hand = 'R' and dir = 3 then 1 end)/
      count(case when hand = 'R' then 1 end) RAvg 
FROM demo 
WHERE name = 'A' 
GROUP BY name 

注意してください、あなたのRAvgが0になりたかった理由は、私は100%で確認されませんでした - 私はあなたが100%を意味仮定。そうでない場合は、それに応じて上記を調整することができます。

+0

これはまさに私が探していたものです.0で割ったときに(null)が得られる場合は0を入れます。 – barracuda