代码之家  ›  专栏  ›  技术社区  ›  oshixun

Postgres中的多个子查询

  •  2
  • oshixun  · 技术社区  · 12 年前

    我开始学习pgsql已经有一段时间了,我正在努力完成我的第一个项目(只是为了测试自己),我一直在努力让这个项目成功。

    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 ( 万一你没注意到, 等级 是一个 character 这就是为什么我 to_char() )来自表格 registration 和列 subjunits 来自表格 subject .

    我发现Postgres不允许多行相乘,或者不允许返回多行。无论哪种方式,我仍然想知道是否有另一种方式获得我所选行的乘积?

    将每个主题放在 WHERE 这个条款很不方便。

    2 回复  |  直到 12 年前
        1
  •  2
  •   Patrick    12 年前
    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 (...) .

        2
  •  2
  •   Craig Ringer    12 年前

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

    接下来,我想你想要的其实是 参加 在子查询上。很难说,因为您没有显示表定义或示例数据。

    我认为Patrick的回答非常正确,指出在这种情况下不需要子查询。这只是一个简单的三向内部连接。如果你 必须将派生自子查询的值相乘,您可以这样做,在 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答案的唯一改进是使用内部连接:

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

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