sql >> データベース >  >> RDS >> PostgreSQL

ヒストグラムデータからのパーセンタイル

    まず、これをアンピボットする必要があります。私たちはこのようにそれを行うことができます...

    SELECT name,
      ARRAY[grade_poor, grade_fair, grade_good, grade_vgood]
    FROM grades
    
     name  |   array   
    -------+-----------
     arun  | {1,4,2,1}
     neha  | {3,2,1,4}
     ram   | {1,1,3,0}
     radha | {0,3,1,4}
    

    次に、グレードにインデックスを付ける必要があります... CROSS JOIN LATERALを使用してインデックスを作成します 。 4つの配列を持つ4つの行があります。4*4行が必要です。

    SELECT name, grades, gs1.x, grades[gs1.x] AS gradeqty
    FROM (
      SELECT name,
        ARRAY[grade_poor, grade_fair, grade_good, grade_vgood]
      FROM grades
    ) AS t(name, grades)
      CROSS JOIN LATERAL generate_series(1,4) AS gs1(x)
    ORDER BY name, x;
    
    
     name  |  grades   | x |  gradeqty
    -------+-----------+---+----------
     arun  | {1,4,2,1} | 1 |        1
     arun  | {1,4,2,1} | 2 |        4
     arun  | {1,4,2,1} | 3 |        2
     arun  | {1,4,2,1} | 4 |        1
     neha  | {3,2,1,4} | 1 |        3
     neha  | {3,2,1,4} | 2 |        2
     neha  | {3,2,1,4} | 3 |        1
     neha  | {3,2,1,4} | 4 |        4
     radha | {0,3,1,4} | 1 |        0
     radha | {0,3,1,4} | 2 |        3
     radha | {0,3,1,4} | 3 |        1
     radha | {0,3,1,4} | 4 |        4
     ram   | {1,1,3,0} | 1 |        1
     ram   | {1,1,3,0} | 2 |        1
     ram   | {1,1,3,0} | 3 |        3
     ram   | {1,1,3,0} | 4 |        0
    (16 rows)
    

    残っているのは、CROSS JOIN LATERALする必要があるということです。 再びx(私たちのグレード)を再現するために、gradeqtyを超えて

    SELECT name,
      gs1.x
    FROM (
      SELECT name,
        ARRAY[grade_poor, grade_fair, grade_good, grade_vgood]
      FROM grades
    ) AS t(name, grades)
    CROSS JOIN LATERAL generate_series(1,4) AS gs1(x)
    CROSS JOIN LATERAL generate_series(1,grades[gs1.x]) AS gs2(x)
    ORDER BY name, gs1.x;
    
     name  | x 
    -------+---
     arun  | 1
     arun  | 2
     arun  | 2
     arun  | 2
     arun  | 2
     arun  | 3
     arun  | 3
     arun  | 4
     neha  | 1
     neha  | 1
     neha  | 1
     neha  | 2
     neha  | 2
     neha  | 3
     neha  | 4
     neha  | 4
     neha  | 4
     neha  | 4
     radha | 2
     radha | 2
     radha | 2
     radha | 3
     radha | 4
     radha | 4
     radha | 4
     radha | 4
     ram   | 1
     ram   | 2
     ram   | 3
     ram   | 3
     ram   | 3
    (31 rows)
    

    次に、GROUP BY name 次に、順序集合集計関数percent_discを使用します 仕事を終えるために..

    SELECT name, percentile_disc(0.5) WITHIN GROUP (ORDER BY gs1.x)
    FROM (
      SELECT name,
        ARRAY[grade_poor, grade_fair, grade_good, grade_vgood]
      FROM grades
    ) AS t(name, grades)
    CROSS JOIN LATERAL generate_series(1,4) AS gs1(x)
    CROSS JOIN LATERAL generate_series(1,grades[gs1.x]) AS gs2(x)
    GROUP BY name ORDER BY name;
    
     name  | percentile_disc 
    -------+-----------------
     arun  |               2
     neha  |               2
     radha |               3
     ram   |               3
    (4 rows)
    

    さらに詳しく調べて、きれいにしたいと思います...

    SELECT name, (ARRAY['Poor', 'Fair', 'Good', 'Very Good'])[percentile_disc(0.5) WITHIN GROUP (ORDER BY gs1.x)]
    FROM (
      SELECT name,
        ARRAY[grade_poor, grade_fair, grade_good, grade_vgood]
      FROM grades
    ) AS t(name, grades)
    CROSS JOIN LATERAL generate_series(1,4) AS gs1(x)
    CROSS JOIN LATERAL generate_series(1,grades[gs1.x]) AS gs2(x)
    GROUP BY name
    ORDER BY name;
    
     name  | array 
    -------+-------
     arun  | Fair
     neha  | Fair
     radha | Good
     ram   | Good
    (4 rows)
    

    新しいユーザーをジャックアップすると、出力が少し多様になります。

    INSERT INTO grades (name,grade_poor,grade_fair,grade_good,grade_vgood)
    VALUES ('Bob', 0,0,0,100);
    
     name  |   array   
    -------+-----------
     arun  | Fair
     Bob   | Very Good
     neha  | Fair
     radha | Good
     ram   | Good
    (5 rows)
    


    1. データベースの最後のN行を順番に取得しますか?

    2. PHPのstrip_tagsに相当するMySQLクエリとは何ですか?

    3. 'IN'句から順序を維持する

    4. MicrosoftAccessのナビゲーションボタンからマクロを実行する方法