在Postgres中乘以子查询

时间:2014-03-16 07:35:00

标签: sql postgresql subquery multiplying

自从我开始学习pgsql以来,我已经有一段时间了,我正在努力完成我的第一个项目(仅仅是为了测试自己),而且我一直在努力使这项工作成功。 / p>

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;

所以,我想做的是将列grade,以防万一你没有注意到,grade是{{1}这就是为什么我从表character中放置to_char())而从表registration放置subjunits列。

我有点发现Postgres不允许多行的乘法,或者它不允许返回多行。无论哪种方式,我仍然想知道是否有另一种方式来获取我选择的行的产品?

将每个主题放在subject子句中非常不方便。

2 个答案:

答案 0 :(得分:2)

首先,请始终使用ANSI加入。它们更具可读性。这意味着from x inner join y on (condition)而不是from x, y where condition

接下来,我认为你想要的是子查询上的 join 。由于您没有显示表定义或样本数据,因此很难说清楚。

我认为帕特里克的回答是正确的,指出在这种情况下你不需要子查询。这只是一个简单的三向内连接。如果确实必须乘以从子查询派生的值,那么你会更喜欢这样做,使用FROM子句中的子查询和INNER JOIN链接子查询,然后SELECT - 列表中的乘法。

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)

然而,在这种情况下,这只是一种可怕的丑陋方式来写上面写的Patrick。不需要子查询。我对Patrick的回答唯一的改进是使用内连接:

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');

接受他的答案,而不是这个。

答案 1 :(得分:2)

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;

您可能希望在选择列表中添加学号。此外,如果您的g.grade类型多于此处排除的四个,则为此添加一列;如果少于四个,则反转该条款:AND g.grade IN (...)