简体   繁体   English

在SQL查询中配对

[英]Making a pair in SQL query

I recently started picking up on SQL, and I am curious about the following 我最近开始学习SQL,并对以下内容感到好奇

There's a table, T, containing the following two columns: 有一个表T,包含以下两列:

student name, score 学生姓名,分数

There is an even number of rows in the table, let's call that number 2N 表中的行数是偶数,我们称其为2N

Is there any easy way to make a new table having the following rows: 有没有简单的方法来制作具有以下行的新表:

highest scorer's name, highest score, lowest scorer's name, lowest score 最高得分者的名字,最高得分,最低得分者的名字,最低得分

2nd highest scorer's name, 2nd highest score, 2nd lowest scorer's name, 2nd lowest score 得分第二高的名字,得分最高的第二个,得分最低的第二个名字,第二得分的第二个

3rd highest scorer's name, 3rd highest score, 3rd lowest scorer's name, 3rd lowest score 最高得分手姓名第三名,最高得分手第三名,最低得分手第三名,最低得分第三名
.
.
.
.
.
Nth highest scorer's name, Nth highest score, Nth lowest scorer's name, Nth lowest score 排名第N的得分手的名字,排名第N的得分的人,得分最低的N的得分手的名字,排名第N的得分最低的人

So there will be N rows total. 因此,总共将有N行。

or is this type of job not suitable in SQL? 还是这种工作不适用于SQL?

It's easy to list the 1st to Nth highest scorer first and 1st to Nth lowest scorer next, but I wasn't sure if there's a way to join them like above nicely in SQL. 首先列出第一个到第N个最高得分者,然后列出第一个到第N个最低得分者很容易,但是我不确定在SQL中是否可以像上面那样很好地加入他们。

You can calculate the row numbers both in ascending and descending order of score and join them on the condition rownumbers are equal. 您可以按分数的升序和降序计算行号,并在条件行数相等的情况下将它们连接起来。

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

If you have odd number (n) of rows in the table the middle row ((n/2)+1 th) would be skipped. 如果表中的行数为奇数(n),则将跳过中间行((n / 2)+1)。

If there can be ties in scores, use the name column to break the tie ie, pick one name over the other (by specifying name ascending or descending in order by ). 如果分数中可以有平局,请使用name列打破平局,即,选择一个名称胜过另一个名称(通过按order by指定名称的升序或降序)。

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,NAME) 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,NAME) Y 
ON X.RNUM = Y.RNUM AND X.SCORE>Y.SCORE

Assuming you have the following data. 假设您具有以下数据。

mysql> select * FROM T;
+--------------+-------+
| student_name | score |
+--------------+-------+
| student 1    |    10 |
| student 2    |     5 |
| student 3    |     1 |
+--------------+-------+
3 rows in set (0.00 sec)

You can order the table by score ascending and descending adding a rank. 您可以通过score升序和降序加表来对表格进行排序。 Then you can join on that rank. 然后,您可以加入该行列。

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

The result for this query for the given data is the following. 该查询针对给定数据的结果如下。

+--------------+-------+--------------+-------+
| 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM