字段列表中的“studentID”列是不明确的?

时间:2015-12-15 11:04:26

标签: sql

我想加入查询,以获得针对同一学生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

2 个答案:

答案 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;