【问题标题】:how does the count function in mysql work?mysql中的count函数是如何工作的?
【发布时间】:2015-11-10 08:11:47
【问题描述】:

首先,这是作业的一部分,但我试图更清楚地了解 count() 函数在查询数据库时是如何工作的。

问题是:列出学生的姓名、SSN和修过的课程数量(不同季度修过的具有相同CourseNumber的课程算作不同的课程)。

我一直在用这个查询:

SELECT S.Name, S.SSN, COUNT(*)
FROM Student S, Enrollment E
WHERE S.SSN = E.SSN
GROUP BY S.SSN

这似乎返回了正确的答案,但我不知道为什么。结果,我似乎无法正确回答下一个问题(假设在不同季度学习的具有相同 CourseNumber 的课程被视为一门课程)。

这里是创建表命令,因此您可以查看哪个表包含哪些信息:

CREATE TABLE Student(
SSN INT(9),
Name VARCHAR(20),
Major VARCHAR(30),
PRIMARY KEY (SSN)
);

CREATE TABLE Course(
CourseNumber INT(5),
PrerequisiteCourseNumber INT(10),
CourseTitle VARCHAR(10),
NumberUnits INT(2),
PRIMARY KEY (CourseNumber)
);

CREATE TABLE Section(
CourseNumber INT(5),
Quarter VARCHAR(10),
RoomNumber INT(5),
DayTime VARCHAR(20),
PRIMARY KEY (CourseNumber,Quarter),
FOREIGN KEY (CourseNumber) REFERENCES Course(CourseNumber)
);


CREATE TABLE Enrollment(
SSN INT(9),
CourseNumber INT(5),
Quarter VARCHAR(10),
Grade VARCHAR(1),
PRIMARY KEY (SSN,CourseNumber,Quarter),
FOREIGN KEY (SSN) REFERENCES Student(SSN),
FOREIGN KEY (CourseNumber) REFERENCES Course(CourseNumber),
FOREIGN KEY (Quarter) REFERENCES Section(Quarter)
);

任何指针?

【问题讨论】:

  • 也许这里有一些关于计数和组的信息:stackoverflow.com/questions/4039194/…
  • 这是作业的一部分 与您的问题无关,但如果 SSN 代表社会安全号码……您永远不会将原始 SSN 存储在数据库表中现实生活;-)
  • @Leigh 当然。只是一个学校作业,所以没有存储真正的 SSN,数据库是本地的。 :)
  • @codenko - 是的,这听起来像是一项学校作业,但是 .. 很高兴听到有常识的人 :-) 你会惊讶于实际上有多少人会存储明文形式的信息......

标签: mysql count


【解决方案1】:

您正在做的是使用旧的连接语法(pre ansi 语法),您可以在其中执行表的交叉连接并使用 where 将其转换为连接。一个等效的查询就是这个。

SELECT S.Name, S.SSN, COUNT(*)
FROM Student S
JOIN Enrollment E ON S.SSN = E.SSN
GROUP BY S.SSN

现在回答你关于计数在做什么和东西的问题..

COUNT() 返回返回的每一行的计数。 GROUP BY 按共同点(即您的 SSN 字段)对所有记录进行分组。因此,如果一个学生在表中有 5 个 SSN 行,那么他的计数将为 5。

现在对于您正在寻找的课程编号部分......您需要在适当的字段中加入这些表格并为每个季度添加一个字段到您的组中

又名添加到前面的代码..

WHERE E.quarter = whatever_quarter_you_want

如果需要,您可以向此查询添加更多内容。但如果您想要更完整的答案,请在您的问题中添加数据。

【讨论】:

  • 谢谢!这现在更有意义了!然而,第二个问题仍然存在问题。我正在使用SELECT S.Name, S.SSN, COUNT(E.CourseNumber) FROM Student S INNER JOIN Enrollment E ON S.SSN = E.SSN GROUP BY S.SSN ,它为我提供了该特定 ssn 的每个名称、ssn 和计算的课程数量,因为该 ssn 存在一个注册行。第二个问题要求提供 SSN 和名称列表,其中包含课程编号不同的课程。我应该为此使用子查询吗?
  • @codenko 如果您想包含所有 ssn 的注册,即使它不存在,您可以尝试将内连接更改为左连接。对于下一部分,您可以再次加入同一个表但是这次指定课程编号不一样又名LEFT JOIN enrollment e1 ON e1.SSN = s.SSN AND e1.CourseNumber <> E.CourseNumber,然后像这样计算COUNT(e1.CourseNumber <> NULL)
  • 检查了答案键,它给出了第二个问题。 SELECT S.SSN, S.Name, Count(*) AS DistinctCourseTaken FROM Student AS S, (SELECT DISTINCT SSN, CourseNumber FROM Enrollment ) AS E WHERE S.SSN = E.SSN GROUP BY S.SSN 我不确定 Distinct 关键字在这种情况下的作用甚至是什么意思。子查询也让我感到困惑。
  • 再次进行交叉连接,这不是一个好主意。使用适当的语法..也许检查你的书是从什么时候开始学习的。那是一种古老的做法。 distinct 正是它听起来的样子。不同的记录......所以如果所有被选择的东西都​​有重复,那么它不会选择它
【解决方案2】:

您当前的查询是:-

SELECT S.Name, S.SSN, COUNT(*)
FROM Student S
INNER JOIN Enrollment E
ON S.SSN = E.SSN
GROUP BY S.SSN

这样做是将学生加入到注册中,因此为每个学生提供多行,为他们注册的每个课程/季度提供一个。然后按 SSN(学生编号?)对其进行分组,以计算他们注册的课程/季度的数量。你真的应该按 S.Name 分组(虽然 MySQL 不会反对,但大多数 SQL 风格都会反对)。

注意 COUNT(*) 计算行数。您可以使用 COUNT(E.CourseNumber) 来计算课程编号不为空的行数。在这里不是很有用,但对 LEFT OUTER JOIN 很有用。您还可以使用 COUNT(DISTINCT CourseNumber) 来计算学生的唯一非空课程编号的数量。

LEFT OUTER JOIN 也可能更好,因为这将使您能够返回 0 作为存在但未注册任何课程的学生的计数:-

SELECT S.Name, S.SSN, COUNT(DISTINCT E.CourseNumber)
FROM Student S
LEFT OUTER JOIN Enrollment E
ON S.SSN = E.SSN
GROUP BY S.Name, S.SSN

【讨论】:

    【解决方案3】:
    SELECT S.Name, S.SSN, COUNT(*)
    FROM Student S, Enrollment E, Section Sec, Course C
    WHERE S.SSN = E.SSN AND E.CourseNumber = Sec.CourseNumber 
    AND Sec.CourseNumber = C.CourseNumber AND Sec.Quarter like E.Quarter
    GROUP BY S.Name, S.SSN
    

    【讨论】:

    • 你真的认为,放弃一些查询应该回答这个问题吗?请提供一些信息或解释,你做了什么以及为什么。
    • 虽然此代码块可能会回答 OP 的问题,但如果您解释此代码的工作原理和原因,以及为什么在不介绍其他代码的情况下解决了问题,则此答案会更有用。
    猜你喜欢
    • 1970-01-01
    • 2023-01-27
    • 1970-01-01
    • 1970-01-01
    • 2014-08-04
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多