【问题标题】:Using COUNT (DISTINCT..) when also using INNER JOIN to join 3 tables but Postgres keeps erroring在使用 INNER JOIN 连接 3 个表时使用 COUNT (DISTINCT..) 但 Postgres 不断出错
【发布时间】:2018-05-06 14:49:19
【问题描述】:

我需要使用 INNER JOIN 来获取一系列信息,然后我需要对这些信息进行计数。我需要能够“查看所有课程和参加课程的讲师、课程的容量以及当前预订课程的成员数量。”

为了获得所有信息,我做了以下查询:

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;

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

我已经弄清楚如何按必要的信息进行计数/分组,例如:

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

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

【问题讨论】:

    标签: sql postgresql count inner-join


    【解决方案1】:

    我认为您正在寻找的是子查询。我是一个 SQL-Server 人(不是 postgresql),但经过一些速成课程 postgresql 谷歌搜索后,这个概念看起来几乎相同。

    无论如何,基本上,当您编写 SELECT 语句时,您可以使用子查询而不是实际的表。所以你的 SQL 看起来像:

    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
    

    ...有意义吗?写出子查询后,您无需再担心它 - 您只需将其视为正在使用的表即可。

    这实际上非常重要,并且可以更轻松地阅读更复杂的查询 - 特别是因为您可以通过解释子查询代表数据的方式来命名子查询。

    【讨论】:

    • 嗨,@Kevin 感谢您的回答!我按照您上面的建议进行了尝试,并得到了错误“FROM 中的子查询必须有别名”所以我然后尝试:SELECT COUNT (*) 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 ) AS courseID;但这只会给我计数,我不能按/分离结果分组,我没有从 INNER JOIN 中获得任何信息......仅限:count bigint 9
    • 再说一次,我不是 postgresql 专家,但在 MS-SQL 中,这样的错误意味着您必须命名子查询。一些简单的事情:选择 count(*) from (select something from somehwere) as mySubQuery。另外,我将扩展我的答案以帮助解释如何考虑子查询。
    • 感谢您的帮助,解释清楚了很多!
    【解决方案2】:

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

    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;
    

    【讨论】:

    • 非常感谢!效果很好!我对 SQL 完全陌生,因此非常感谢您的帮助!
    • 很高兴为您提供帮助@user8992790
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-09
    • 2015-10-09
    • 2015-05-16
    • 1970-01-01
    相关资源
    最近更新 更多