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

使用计数(不同..)当也使用内部连接连接3个表时,但Postgres不断出错

  •  0
  • user8992790  · 技术社区  · 8 年前

    我需要使用内部连接来获得一系列信息,然后我需要计算这些信息。我需要能够“查看所有课程和参加课程的讲师、课程的容量以及当前预订的课程成员数量。”

    SELECT
        C.coursename, Instructors.fname, Instructors.lname,C.maxNo, membercourse.memno
    FROM Courses AS C
    INNER JOIN Instructors ON C.instructorNo = Instructors.instructorNo
    INNER JOIN Membercourse ON C.courseID = Membercourse.courseID;
    

    但无论我把计数放在哪里,它总是告诉我,计数之外的任何东西都应该在组中

    我已经学会了如何根据必要的信息进行计数/分组,例如:

    SELECT courseID, COUNT (DISTINCT MC.memno)
    FROM Membercourse AS MC
    GROUP BY MC.courseID;
    

    但我不知道如何将两者结合起来!

    2 回复  |  直到 8 年前
        1
  •  1
  •   Kevin    8 年前

    我想你要找的是一个子查询。我是一个SQL Server的家伙(不是postgresql),但在一些速成班的postgresql谷歌搜索之后,这个概念看起来几乎是一样的。

    select count(*)
    from
    (
        select stuff from table
        inner join someOtherTable
    )
    

    ... 希望这是有道理的。与其尝试编写一个大查询来同时进行内部连接和计数,不如编写两个:一个是获取内部连接数据的内部查询,另一个是实际计算行数的外部查询。

    编辑:帮助进一步解释子查询背后的思维过程。

    子查询是对数据上的步骤/过程进行逻辑分解的一种方法。不要试图一大步完成每件事,你要分步做。

    在这种情况下,第一步是什么?它是为您的组合、内部连接数据获取一个组合数据源。

    步骤1:编写内部连接查询

    SELECT
        C.coursename, Instructors.fname, Instructors.lname,C.maxNo, 
    membercourse.memno
    FROM Courses AS C
    INNER JOIN Instructors ON C.instructorNo = Instructors.instructorNo
    INNER JOIN Membercourse ON C.courseID = Membercourse.courseID;
    

    好了,接下来呢?

    好吧,假设我们想得到一个计数,在上面的结果中,每个“memno”有多少个条目。

    而不是试图找出如何 修改 我们将上面的查询用作数据源,就像它本身是一个表一样。

    步骤2-使其成为子查询

    select * from
    (
        SELECT
            C.coursename, Instructors.fname, Instructors.lname,C.maxNo, 
        membercourse.memno
        FROM Courses AS C
        INNER JOIN Instructors ON C.instructorNo = Instructors.instructorNo
        INNER JOIN Membercourse ON C.courseID = Membercourse.courseID
    ) mySubQuery
    

    第3步-修改外部查询以获取所需的数据。

    好吧,我们想按“memno”分组,然后得到计数,对吗?所以

    select memno, count(*)
    from
    (
        -- all that same subquery stuff
    ) mySubQuery
    group by memno
    

    ... 有道理?一旦您写出了子查询,您就不需要再担心它了——您只需将其视为正在处理的表。

    这实际上非常重要,并且使阅读更复杂的查询变得更容易——特别是因为您可以以解释子查询代表数据的方式命名子查询。

        2
  •  0
  •   Michel Milezzi    8 年前

    有很多方法可以解决这个问题,例如使用窗口函数等等。但您也可以使用一个简单的子查询来实现它:

    SELECT
        C.coursename, 
        Instructors.fname, 
        Instructors.lname, 
        C.maxNo, 
        (SELECT 
            COUNT(*) 
        FROM 
            membercourse 
        WHERE 
            C.courseID = Membercourse.courseID) AS members
    FROM 
        Courses AS C
        INNER JOIN Instructors ON C.instructorNo = Instructors.instructorNo;