Links

   Quran Explorer - Interactive Audio Recitations & Translations

Tuesday, March 12, 2013

CrossTab query in Postgres

Hello,

Ever wondered how to display the following output via an SQL query?

StudentCalculusSimmulationProgrammingComm Skills
Ibrahim Itambo67988359
Abdulswamad68947740
Shamim70765644
Samira36986890

There are several ways of doing it but the most common and annoying hack is to use CASE...WHEN and/or aggregate functions with GROUP BY.

It may work but they are usualy overly complex, unreadable and hard to maintain.

A better solution in Postgres is to use crosstab function available via the tablefunc module.


Example code

CREATE TABLE student(
student_id serial primary key,
student_name varchar(50),
remarks test
);
INSERT INTO student(student_name) VALUES('Ibrahim');
INSERT INTO student(student_name) VALUES('Kilui');
INSERT INTO student(student_name) VALUES('Ali Babababa');
INSERT INTO student(student_name) VALUES('Buzi');

CREATE TABLE subject(
subject_id serial primary key,
subject_name varchar(50),
remarks text
);

INSERT INTO subject(subject_name) VALUES('Calculus I');
INSERT INTO subject(subject_name) VALUES('Simulation');
INSERT INTO subject(subject_name) VALUES('Adv Programming');
INSERT INTO subject(subject_name) VALUES('Comm Skills');

CREATE TABLE exam(
exam_id serial primary key,
exam_title varchar(50),
student_id integer references student,
subject_id integer references subject,
exam_mark real default 0 not null,
remarks text
);
//FINALY INSERT RESULTS
//INSERT INTO exam(exam_title, student_id, subject_id, exam_mark) VALUES(......); you know what to do here

SELECT * FROM crosstab(
    'select student.student_name::text, subject.subject_name, exam.exam_mark
    from exam
    inner join student on exam.student_id = student.student_id
    inner join subject on exam.subject_id = subject.subject_id
    order by 1,2',
    'SELECT subject_name FROM subject ORDER BY 1')
AS
  CT("Student" text, "Calculus" real, "Simulation" real, "Prog" real, "Comm Skills" real);


Adios

No comments:

Post a Comment

Feel free to leave a comment