请帮我分解一下这个MySQL语句



我在课堂上通过拼凑互联网知识想出了这个解决方案。请帮我分解一下,我很想知道我是如何做到的。特别是t.s和关闭的t.

SELECT 
CourseType, 
GPA, 
NumberOfStudents * 100 / t.s AS `Percentage of Students`
FROM View1 
CROSS JOIN 
( 
SELECT 
SUM(NumberOfStudents) AS s 
FROM View1) t;

您的查询使用子查询。子查询是在另一个查询中完成的查询。在您的情况下,您的子查询是:

( 
SELECT 
SUM(NumberOfStudents) AS s 
FROM View1)

创建子查询时,需要给它们一个别名。别名只是为子查询提供的名称,因此您可以在主查询中使用它。在您的示例中,您将子查询命名为";t";。

字段也可以有别名。在子查询中,您创建了一个字段SUM(NumberOfStudents),并将其命名为s。

回到您的问题,您使用别名来寻址子查询中的字段。在你的情况下,当你做100 / t.s时,你基本上是在说:

"我想把100除以来自我的子查询t〃的字段s;。

查询中另一个重要的概念是交叉联接。交叉连接是两个表的笛卡尔乘积。

您可以在以下链接中找到一个关于交叉连接如何工作的直观解释:

https://www.sqlshack.com/sql-cross-join-with-examples/#:~:text=%20CROSS%20JOIN%20已使用,也%20已知%20为%20笛卡尔%20联接&text=%20主%20创意%20,%20产品%20加入%20表格。

在这种情况下,使用比那更简单。子查询应该只返回一个值,即所有学生的总和。由于交叉联接基本上是将一个表的每一行与另一个表中的每一行都配对,因此交叉联接只是提供了一种使用学生人数作为常量来计算主查询中学生百分比的方法。

一种更好的方法是使用窗口函数:

SELECT v.CourseType, v.GPA, 
v.NumberOfStudents * 100 / SUM(v.NumberOfStudents) OVER () AS Percentage_of_Students
FROM View1 v;

如果您正在学习SQL,那么不妨学习正确的逻辑表达方式。

注:

  • 使用有意义的表别名(表/视图名称的缩写(
  • 限定列引用。在只有一个表引用的查询中,这并不重要,但这是一个好习惯
  • 窗口函数允许您在不使用显式JOIN的情况下跨多行汇总数据

最新更新