Mysql SQL查询中的配对
我最近开始学习SQL,我对以下内容感到好奇 有一个表T,包含以下两列: 学生姓名、成绩 表中有偶数行,我们称之为2N 有没有简单的方法可以创建包含以下行的新表: 得分最高者姓名、得分最高者姓名、得分最低者姓名、得分最低者姓名 第二高分者姓名,第二高分,第二低分者姓名,第二低分 第三高得分者姓名、第三高得分、第三低得分者姓名、第三低得分Mysql SQL查询中的配对,mysql,sql,Mysql,Sql,我最近开始学习SQL,我对以下内容感到好奇 有一个表T,包含以下两列: 学生姓名、成绩 表中有偶数行,我们称之为2N 有没有简单的方法可以创建包含以下行的新表: 得分最高者姓名、得分最高者姓名、得分最低者姓名、得分最低者姓名 第二高分者姓名,第二高分,第二低分者姓名,第二低分 第三高得分者姓名、第三高得分、第三低得分者姓名、第三低得分 . . . . . 第N个得分最高者姓名,第N个得分最高者姓名,第N个得分最低者姓名,第N个得分最低者姓名 所以总共有N行 或者这种类型的作业不适合SQL 首先列
.
.
.
.
.
第N个得分最高者姓名,第N个得分最高者姓名,第N个得分最低者姓名,第N个得分最低者姓名 所以总共有N行 或者这种类型的作业不适合SQL
首先列出第一个到第n个得分最高的人,然后列出第1个到第n个得分最低的人很容易,但我不确定是否有一种方法可以像上面那样在SQL中很好地将他们连接起来。假设您有以下数据
mysql> select * FROM T;
+--------------+-------+
| student_name | score |
+--------------+-------+
| student 1 | 10 |
| student 2 | 5 |
| student 3 | 1 |
+--------------+-------+
3 rows in set (0.00 sec)
您可以通过score
升序和降序添加秩对表格进行排序。然后你就可以加入这个行列了
SELECT high.student_name, high.score, low.student_name, low.score FROM
(SELECT @n:=@n+1 AS ord, student_name, score
FROM T, (SELECT @n:=0) n
ORDER BY score DESC) AS high
JOIN
(SELECT @m:=@m+1 AS ord, student_name, score
FROM T, (SELECT @m:=0) m
ORDER BY score ASC) AS low
ON high.ord = low.ord
此查询对给定数据的结果如下所示
+--------------+-------+--------------+-------+
| student_name | score | student_name | score |
+--------------+-------+--------------+-------+
| student 1 | 10 | student 3 | 1 |
| student 2 | 5 | student 2 | 5 |
| student 3 | 1 | student 1 | 10 |
+--------------+-------+--------------+-------+
3 rows in set (0.00 sec)
假设您有以下数据
mysql> select * FROM T;
+--------------+-------+
| student_name | score |
+--------------+-------+
| student 1 | 10 |
| student 2 | 5 |
| student 3 | 1 |
+--------------+-------+
3 rows in set (0.00 sec)
您可以通过score
升序和降序添加秩对表格进行排序。然后你就可以加入这个行列了
SELECT high.student_name, high.score, low.student_name, low.score FROM
(SELECT @n:=@n+1 AS ord, student_name, score
FROM T, (SELECT @n:=0) n
ORDER BY score DESC) AS high
JOIN
(SELECT @m:=@m+1 AS ord, student_name, score
FROM T, (SELECT @m:=0) m
ORDER BY score ASC) AS low
ON high.ord = low.ord
此查询对给定数据的结果如下所示
+--------------+-------+--------------+-------+
| student_name | score | student_name | score |
+--------------+-------+--------------+-------+
| student 1 | 10 | student 3 | 1 |
| student 2 | 5 | student 2 | 5 |
| student 3 | 1 | student 1 | 10 |
+--------------+-------+--------------+-------+
3 rows in set (0.00 sec)
您可以按分数的升序和降序计算行号,并在行号相等的条件下将它们合并
SELECT X.NAME,
X.SCORE,
Y.NAME,
Y.SCORE
FROM
(SELECT NAME,SCORE,@RN_ASC:=@RN_ASC+1 AS RNUM
FROM T
CROSS JOIN (SELECT @RN_ASC:=0) R
ORDER BY SCORE) X
JOIN
(SELECT NAME,SCORE,@RN_DESC:=@RN_DESC+1 AS RNUM
FROM T
CROSS JOIN (SELECT @RN_DESC:=0) R
ORDER BY SCORE DESC) Y
ON X.RNUM = Y.RNUM AND X.SCORE>Y.SCORE
如果表中有奇数(n)行,则将跳过中间行((n/2)+第1行)
如果分数中可能存在平局,请使用名称
列打破平局,即选择一个名称而不是另一个名称(通过指定名称按顺序升序或降序)
您可以按分数的升序和降序计算行号,并在行号相等的条件下将它们合并
SELECT X.NAME,
X.SCORE,
Y.NAME,
Y.SCORE
FROM
(SELECT NAME,SCORE,@RN_ASC:=@RN_ASC+1 AS RNUM
FROM T
CROSS JOIN (SELECT @RN_ASC:=0) R
ORDER BY SCORE) X
JOIN
(SELECT NAME,SCORE,@RN_DESC:=@RN_DESC+1 AS RNUM
FROM T
CROSS JOIN (SELECT @RN_DESC:=0) R
ORDER BY SCORE DESC) Y
ON X.RNUM = Y.RNUM AND X.SCORE>Y.SCORE
如果表中有奇数(n)行,则将跳过中间行((n/2)+第1行)
如果分数中可能存在平局,请使用名称
列打破平局,即选择一个名称而不是另一个名称(通过指定名称按顺序升序或降序)
出于好奇,是否有任何理由将@放在RN_ASC和RN_DESC之前,并使用:=而不是=?请阅读此处。明白了,但当您定义RN_ASC:=RN_ASC+1时,上述函数是否保证RN_ASC将按分数升序排序?SQL中的“ORDER BY”函数就是这样工作的吗?可能是因为我不熟悉SQL,但上面的函数似乎会先定义RN_ASC值,然后按分数、名称排序。如果SQL不是这样工作的,那么我为自己缺乏知识而道歉。
@RN\u ASC:=0
初始化变量,查询根据分数的升序分配值。@RN\u DESC
也类似。只是出于好奇,是否有任何理由将@放在RN\u ASC和RN\u DESC之前,并使用:=而不是=?请阅读此处。明白了,但当您定义RN\u ASC:=RN\u ASC+1时,上述函数是否保证RN\u ASC将按分数升序排序?SQL中的“ORDER BY”函数就是这样工作的吗?可能是因为我不熟悉SQL,但上面的函数似乎会先定义RN_ASC值,然后按分数、名称排序。如果SQL不是这样工作的,那么我为自己缺乏知识而道歉。@RN\u ASC:=0
初始化变量,查询根据分数的升序分配值。这与@RN_DESC
也类似。