Question

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.

Was it helpful?

Solution

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 (...).

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top