Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql SQL查询中的配对_Mysql_Sql - Fatal编程技术网

Mysql SQL查询中的配对

Mysql SQL查询中的配对,mysql,sql,Mysql,Sql,我最近开始学习SQL,我对以下内容感到好奇 有一个表T,包含以下两列: 学生姓名、成绩 表中有偶数行,我们称之为2N 有没有简单的方法可以创建包含以下行的新表: 得分最高者姓名、得分最高者姓名、得分最低者姓名、得分最低者姓名 第二高分者姓名,第二高分,第二低分者姓名,第二低分 第三高得分者姓名、第三高得分、第三低得分者姓名、第三低得分 . . . . . 第N个得分最高者姓名,第N个得分最高者姓名,第N个得分最低者姓名,第N个得分最低者姓名 所以总共有N行 或者这种类型的作业不适合SQL 首先列

我最近开始学习SQL,我对以下内容感到好奇

有一个表T,包含以下两列:

学生姓名、成绩

表中有偶数行,我们称之为2N

有没有简单的方法可以创建包含以下行的新表:

得分最高者姓名、得分最高者姓名、得分最低者姓名、得分最低者姓名

第二高分者姓名,第二高分,第二低分者姓名,第二低分

第三高得分者姓名、第三高得分、第三低得分者姓名、第三低得分
.
.
.
.
.
第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
也类似。