我想加入查询,以获得针对同一学生ID的两个表格中的分数排名。
我的查询有什么问题?
SELECT
studentID,
mark,
(
SELECT
COUNT(*)+ 1
FROM
ca B
WHERE
A.mark < B.mark
) AS Rank
FROM
ca A INNER JOIN mark on ca.studentID = mark.studentID
ORDER BY
mark DESC
答案 0 :(得分:1)
在您的代码中考虑以下行:
INNER JOIN mark on ca.studentID = mark.studentID
studentID 是2个表格中的列名称(ca和标记)
因为有两个相同的名称,所以只使用列名本身就是“含糊不清”。想象一下在办公室派对上有一个人的房间,其中两个人的名字叫保罗。如果你在房间里喊“保罗”,那么保罗你想吸引哪个人呢?
所以:总是使用你的别名来确保你的查询避免含糊不清
SELECT
A.studentID
, mark.mark
, (
SELECT
COUNT(*) + 1
FROM ca B
WHERE A.mark < B.mark
)
AS Rank
FROM ca A
INNER JOIN mark ON A.studentID = mark.studentID
ORDER BY
mark.mark DESC
还值得指出的是,您已经使用别名A对表ca
FROM ca A
所以,因为有一个别名(A),你现在必须使用该别名而不是表名(ca)
但是,对于另一个表(标记),您尚未声明别名,因此您使用表的名称而不是别名,例如。
选择 A .studentID,标记 .mark
答案 1 :(得分:0)
您的直接问题是列上缺少的表别名。这可能会混淆SQL。而且,我们不想混淆SQL。因此,请使用合格的列名称。
此外,我猜测列mark
实际上在表mark
中,而不是ca
。这对我来说似乎合乎逻辑。我在下面做了这个假设,但很容易将逻辑切换回ca
。
大多数数据库都支持ANSI标准窗口函数。在这样的数据库中,您可以使用更简单的方法:
select a.studentId, m.mark,
rank() over (partition by a.studentId order by m.mark) as rank
from ca a join
mark m
on a.studentID = m.studentId
order by m.mark;
我应该注意到,您似乎甚至不需要join
,因为studentId
位于两个表格中。所以,这可能是等价的:
select m.studentId, m.mark,
rank() over (partition by m.studentId order by m.mark) as rank
from mark m
order by m.mark;
如果您不需要join
,那么也会使用子查询修复您的版本。但是,表别名仍然是一个好主意:
SELECT m.studentID, m.mark,
(SELECT COUNT(*) + 1
FROM mark m2
WHERE m.mark < m2.mark
) AS Rank
FROM mark m
ORDER BY m.mark DESC;