我最近开始学习SQL,我很好奇以下
有一个表T,包含以下两列:
学生姓名,得分
表中有偶数行,我们称之为2N
有没有简单的方法来制作一个包含以下行的新表:
得分最高的名字,得分最高,得分最低的得分,得分最低
第二高得分手的名字,第二高分,第二低得分手的名字,第二低的得分
第三高得分手的名字,第三高分,第三低得分手的名字,第三低的得分
。
。
。
。
。
Nth得分最高的名字,Nth得分最高,N得分最低的得分,Nth得分
所以总共会有N行。
或者这种类型的工作不适合SQL吗?
很容易列出第一到第N个最高得分手,然后是第一个到第N个最低得分手,但是我不确定是否有办法在SQL中很好地加入他们。
答案 0 :(得分:2)
您可以按分数的升序和降序计算行数,并在rownumbers相等的条件下加入它们。
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 th)。
如果分数中存在关联,请使用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
答案 1 :(得分:1)
假设您有以下数据。
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)