Reputation: 47
It's been a while since I started to learn pgsql and I'm trying to work on my first project (just to test myself) and I've been trying to make this work.
SELECT ((SELECT to_number(g.grade, '9D99') AS numgrade
FROM grade g, registration r
WHERE g.grade_id=r.grade_id
AND g.grade!='INC'
AND g.grade!='INP'
AND g.grade!='W'
AND g.grade!='DRP')*(SELECT s.subjunits
FROM subject s, registration r
WHERE s.subjcode=r.subjcode)) AS product
FROM subject s, registration r;
So, what I want to do is multiply the column grade
(just in case you didn't notice, column grade
is a character
which is why I put to_char()
) from table registration
and column subjunits
from table subject
.
I kind of figured out that Postgres doesn't allow multiplying of multiple rows or maybe it doesn't allow returning of multiple rows. Either way I still wanted to know if there's another way getting the product of the rows that I have selected?
Putting every single subject in the WHERE
clause is very inconvenient.
Upvotes: 2
Views: 1721
Reputation: 324731
First, please always use ANSI
joins. They're much more readable. That means from x inner join y on (condition)
instead of from x, y where condition
.
Next, I think what you want here is actually a join on the subqueries. It's hard to tell since you have not shown your table definitions or sample data.
I think Patrick's answer is quite right in pointing out that you do not need subqueries in this case. It's just a simple three-way inner join. If you did have to multiply values derived from subqueries, you would do it more like this, with subqueries in the FROM
clause and an INNER JOIN
to link the subqueries, then the multiplication in the SELECT
-list.
SELECT
ng.numgrade * su.subjunits
FROM
(
SELECT
r.subjcode,
to_number(g.grade, '9D99') AS numgrade
FROM grade g INNER JOIN registration r ON (g.grade_id=r.grade_id )
WHERE g.grade NOT IN ('INC', 'INP', 'W', 'DRP')
) ng
INNER JOIN
(
SELECT
s.subjcode,
s.subjunits
FROM subject s, registration r
WHERE s.subjcode=r.subjcode
) su
ON (su.subjcode = ng.subjcode)
However, in this case this is just a hideously ugly way of writing what Patrick wrote above. No subqueries are necessary. The only improvement I'd make on Patrick's answer is using inner joins:
SELECT
g.student_id, -- or whatever your key is
s.subjcode,
(to_number(g.grade, '9D99') * s.subjunits) AS product
FROM grade g
INNER JOIN registration r ON (g.grade_id = r.grade_id)
INNER JOIN subject s ON (r.subjcode = s.subjcode)
WHERE g.grade NOT IN ('INC', 'INP', 'W', 'DRP');
Accept his answer, not this one.
Upvotes: 2
Reputation: 32296
SELECT (to_number(g.grade, '9D99') * s.subjunits) AS product
FROM grade g, registration r, subject s
WHERE g.grade_id = r.grade_id
AND g.grade NOT IN ('INC', 'INP', 'W', 'DRP')
AND s.subjcode = r.subjcode;
You probably want to add a student number in your select list. Also, if your g.grade types are many more then the four here excluded, add a column for that; if there are fewer than four, then reverse the clause: AND g.grade IN (...)
.
Upvotes: 2