I have a table name test
first last
raj kumar
raj patel
there is hundreds of row in this table.
I have another table called class
having all the names that are present in the test
table and its marks for each subject.
class_id first_name last_name subject marks
1 raj kumar physics 70
1 raj kumar chemistry 70
1 raj patel physics 80
1 raj kumar math 90
1 raj kumar computer 80
1 raj patel chemistry 90
1 raj patel math 100
2 raj kumar physics 70
2 raj kumar chemistry 70
2 raj patel physics 80
2 raj kumar math 90
2 raj kumar computer 80
2 raj patel chemistry 90
2 raj patel math 100
Now i want to know the total marks of each student present in the test
table in below format :.
class_id raj.kumar raj.patel
1 310 270
2 n m
So there will be n
number of columns in the resulting tbale
for this particular case we can write
select class_id
sum(case when first_name = 'raj' and last_name = 'Kumar' then marks else 0) as "raj.kumar",
sum(case when first_name = 'raj' and last_name = 'patel' then marks else 0)as "raj.patel"
from class
group by class_id
Since number of students is not fixed which is present in the test
table. so i don't want to hardcode the first and last name in my query. I want something like this which could be able to calculate marks for all the students which are present on test
table.
select class_id,
for(i = 0; i < test.size; i++)
sum(case when first_name = i.first and last_name = i.last then marks else 0 ) as i.first|| '.' ||i.last,
from class
group class_id
How to write query or stored procedure for this thanks in advance.
I am using postgresql.
For all students?
What is wrong with:
select class_id, first_name, last_name, sum(marks)
from class
group by class_id, first_name, last_name;
So you want a crosstab. Here the main problem is that the planner needs to know how many columns and what their types are before starting. So the bad news is there is no direct way to do this.
So you have a few options:
tablefunc
extension and dynamically generate your query around the crosstab()
function xml
or json
types and return objects or documents rather than records. EDIT To be clear your problem is a planner limitation. You cannot have expand a column list into a variable number of columns. So you have to generate the SQL from outside the db. You cannot handle a dynamic number of columns directly in SQL.
Now, I would highly recommend using the crosstab() function from the tablefunc extension because this simplifies conceptually the result quite a bit. If you have to do this manually (please don't) you can write a query generator in pl/perl or pl/pgsql by selecting from the other table, and then use pl/pgsql's EXECUTE into a cursor. You can then return a refcursor.
This is not ideal because the client then has to FETCH
from the returned refcursor.
So your first point is to decide on where you are going to generate the SQL code that will run. Will this be in a database client? Or in dynamic SQL (with a requirement that the client FETCH rows separately from running the function)?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.