带有动态列和联接计数的PostgreSQL查询 [英] PostgreSQL Query with dynamic columns and counts from join

查看:81
本文介绍了带有动态列和联接计数的PostgreSQL查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可能对此考虑过多,因为我不太确定从哪里开始...

I'm probably overthinking this, because I'm not really sure where to start... But here goes:

我有以下

学生

评估

学生评估

student_id | Assessment 1 | Assessment 2 | Assessment 3 | Assessment 4
1            3              1              2              0
2            1              0              0              0
3            2              1              1              0
4            5              3              3              0
5            1              5              0              0
6            2              1              2              0

第二次查询通过"

student_id | Assessment 1 | Assessment 2 | Assessment 3 | Assessment 4
1            t              t              f              f
2            t              t              f              f
3            t              t              f              f
4            t              t              t              f
5            t              t              f              f
6            t              t              t              f

让我大跌眼镜的部分不是进行每次评估的联接,甚至没有手动定义列,而是生成"每个评估存在的列.

The part that is tripping me up is not doing a join for EVERY assessment, and not even defining the columns manually but rather "generating" each column for assessments that exist.

我觉得这很简单,我太劳累了,无法立即解决:)预先感谢您的帮助,这是

I feel like it's simple, and I am just too overworked to figure it out right now :) thank you in advance for your help, and here's a SQL Fiddle of data as an example

推荐答案

查询"的简单查询,

select student_id,sum(case when assessment_id=1 then 1 else 0 end) as "Assessment 1",
sum(case when assessment_id=2 then 1 else 0 end) as "Assessment 2",
sum(case when assessment_id=3 then 1 else 0 end) as "Assessment 3",
sum(case when assessment_id=4 then 1 else 0 end) as "Assessment 4",
sum(case when assessment_id=5 then 1 else 0 end) as "Assessment 5",
sum(case when assessment_id=6 then 1 else 0 end) as "Assessment 6"
from assessments_students
group by student_id
order by student_id

在crosstab()函数中,还需要显式定义列名称,例如评估1",评估2"等等.

In crosstab() function also, need to define columns name explicitly like "Assessment 1","Assessment 2" and so on.

或编写用于创建动态查询的自定义函数,然后使用EXECUTE语句执行.

Or write custom function for creating dynamic query, and execute using EXECUTE statement.

DROP FUNCTION get_Attempts() ;

CREATE OR REPLACE FUNCTION get_Attempts() RETURNS text AS
$BODY$
DECLARE
        r1 record;
        str_query text := '';
 BEGIN
    str_query :='select student_id,';
    FOR r1 IN SELECT "_id" , "name" FROM Assessments
    LOOP
      str_query:= str_query || 
                  'sum(case when assessment_id=' || r1."_id" || ' then 1 else 0 end) as  "' || r1.name ||'",' ;
    END LOOP;
    str_query:=trim( trailing  ',' from str_query); -- remove last semicolon
    str_query:= str_query || ' from assessments_students group by student_id order by student_id';
    return str_query;
END
$BODY$
LANGUAGE 'plpgsql' ;

SELECT * FROM get_Attempts();


第二次查询通过"


Second query for "passed"

select student_id,
max(case when assessment_id=1 and passed='t' then 't' else 'f' end) as  "Assessment 1",
max(case when assessment_id=2 and passed='t' then 't' else 'f' end) as  "Assessment 2",
max(case when assessment_id=3 and passed='t' then 't' else 'f' end) as  "Assessment 3",
max(case when assessment_id=4 and passed='t' then 't' else 'f' end) as  "Assessment 4",
max(case when assessment_id=5 and passed='t' then 't' else 'f' end) as  "Assessment 5",
max(case when assessment_id=6 and passed='t' then 't' else 'f' end) as  "Assessment 6" 
from assessments_students 
group by student_id 
order by student_id

它的功能看起来像

DROP FUNCTION get_passed() ;

CREATE OR REPLACE FUNCTION get_passed() RETURNS text AS
$BODY$
DECLARE
        r1 record;
        str_query text := '';
 BEGIN
    str_query :='select student_id,';
    FOR r1 IN SELECT "_id" , "name" FROM Assessments
    LOOP
      str_query:= str_query || 
                  'max(case when assessment_id=' || r1."_id" || ' and passed=''t'' then ''t'' else ''f'' end) as  "' || r1.name ||'",' ;
    END LOOP;
    str_query:=trim( trailing  ',' from str_query); -- remove last semicolon
    str_query:= str_query || ' from assessments_students group by student_id order by student_id';

    return str_query;
END
$BODY$
LANGUAGE 'plpgsql' ;

SELECT * FROM get_passed();

这篇关于带有动态列和联接计数的PostgreSQL查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆