sql - हिस्टोग्राम डेटा से प्रतिशतियल्स




postgresql (2)

निम्न सारणी कई परीक्षाओं पर छात्र ग्रेड डेटा को कैप्चर करता है

CREATE TABLE grades
AS
  SELECT name, exams, grade_poor, grade_fair, grade_good, grade_vgood
  FROM ( VALUES
    ( 'arun'  , 8  , 1 , 4 , 2 , 1 ),
    ( 'neha'  , 10 , 3 , 2 , 1 , 4 ),
    ( 'ram'   ,  5 , 1 , 1 , 3 , 0 ),
    ( 'radha' ,  8 , 0 , 3 , 1 , 4 )
  ) AS t(name,exams,grade_poor,grade_fair,grade_good,grade_vgood);

ग्रेड को इस अर्थ में आदेश दिया जाता है कि vgood> अच्छा> निष्पक्ष> गरीब

क्या इस डेटा के साथ प्रत्येक छात्र के 50 वें प्रतिशतय ग्रेड को खोजना संभव होगा (या क्या यह समझ जाएगा)? उदाहरण के लिए - यदि हम ग्रेड श्रेणी की श्रेणियों के रूप में डेटा के बारे में सोचते हैं तो - 50 वीं प्रतिशतक grade_fair होगा।


SELECT name, exams,
       CASE WHEN 0.5 * exams <= grade_poor
                THEN 'grade_poor'
            WHEN 0.5 * exams <= grade_poor + grade_fair
                THEN 'grade_fair'
            WHEN 0.5 * exams <= grade_poor + grade_fair + grade_good
                THEN 'grade_good'
            ELSE 'grade_vgood' END AS median_grade;

इस दौर का संबंध तो नीचे आता है ताकि न्हा "ग्रेड_फेयर" स्कोर कर सकें और राधा "ग्रेड_गुड" स्कोर कर सकें। यदि आप गोल करना चाहते हैं, तो <= इन <


पहले आपको इसे अनपिट करना होगा। हम ऐसा कर सकते हैं ...

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)

अब क्या बनी हुई है, हमें कक्षा (ग्रेडिंग) पर एक्स (हमारे ग्रेड) को पुन: उत्पन्न करने के लिए फिर से जोड़ना आवश्यक है

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)






postgresql