如何将此查询从MySQL转换为SQL Server?

如何将此查询从MySQL转换为SQL Server?,mysql,sql,sql-server,Mysql,Sql,Sql Server,以下是源表: +----+-------+ | Id | Score | +----+-------+ | 1 | 3.50 | | 2 | 3.65 | | 3 | 4.00 | | 4 | 3.85 | | 5 | 4.00 | | 6 | 3.65 | +----+-------+ 以下是结果表: +-------+------+ | Score | Rank | +-------+------+ | 4.00 | 1 | | 4.00 | 1 |

以下是源表:

+----+-------+
| Id | Score |
+----+-------+
| 1  | 3.50  |
| 2  | 3.65  |
| 3  | 4.00  |
| 4  | 3.85  |
| 5  | 4.00  |
| 6  | 3.65  |
+----+-------+
以下是结果表:

+-------+------+
| Score | Rank |
+-------+------+
| 4.00  | 1    |
| 4.00  | 1    |
| 3.85  | 2    |
| 3.65  | 3    |
| 3.65  | 3    |
| 3.50  | 4    |
+-------+------+
我有MySQL版本查询,如何将其转换为SQL server版本?我试图做声明,但我不知道如何更新变量的值

SELECT Score, ranking AS Rank
FROM
(
SELECT 
    Score,
    CASE
        WHEN @dummy = Score 
        THEN @ranking := @ranking
        ELSE @ranking := @ranking + 1
    END as ranking,
    @dummy := Score
FROM Scores, (SELECT @ranking := 0, @dummy := -1) init 
ORDER BY Score DESC
)AS Result

正如Sean Lange在一篇评论中解释的那样,您的代码是针对ANSI标准稠密等级函数的MySQL解决方案。代码看起来很简单:

SELECT s.*, DENSE_RANK() OVER (ORDER BY Score DESC) as rank
FROM Scores s
ORDER BY Score DESC;
顺便说一句,MySQL代码本身并不准确。以下情况更安全:

SELECT Score, ranking AS Rank
FROM (SELECT Score,
             (@rn := if(@dummy = Score, @rn,
                             if(@dummy := Score, @rn + 1, @rn + 1)
                            )
             ) as ranking
      FROM Scores CROSS JOIN
           (SELECT @rn := 0, @dummy := -1) init 
      ORDER BY Score DESC
     ) s;

关键区别在于所有变量赋值都发生在一个表达式中。MySQL不保证SELECT中表达式的求值顺序,因此您不应该在一个表达式中使用@dummy,然后在另一个表达式中分配它。

您的代码是针对ANSI标准稠密等级函数的MySQL变通方法,正如Sean Lange在注释中解释的那样。代码看起来很简单:

SELECT s.*, DENSE_RANK() OVER (ORDER BY Score DESC) as rank
FROM Scores s
ORDER BY Score DESC;
顺便说一句,MySQL代码本身并不准确。以下情况更安全:

SELECT Score, ranking AS Rank
FROM (SELECT Score,
             (@rn := if(@dummy = Score, @rn,
                             if(@dummy := Score, @rn + 1, @rn + 1)
                            )
             ) as ranking
      FROM Scores CROSS JOIN
           (SELECT @rn := 0, @dummy := -1) init 
      ORDER BY Score DESC
     ) s;

关键区别在于所有变量赋值都发生在一个表达式中。MySQL不保证SELECT中表达式的求值顺序,因此不应在一个表达式中使用@dummy,然后在另一个表达式中分配它。

SQL Server不支持以这种方式使用变量,因此语法不会转换。标量变量由查询设置一次,而不是为结果集的每一行设置一次。MySQL在这里的语法是一种在没有分析函数支持的情况下获得类似于分析函数的行为的攻击。您只需使用:

SELECT Score,
    DENSE_RANK() OVER(ORDER BY Score DESC) AS Rank
FROM Scores
ORDER BY Score DESC;
如果坚持不使用DENSE_RANK,可以使用SQL Server 2000中的SQL Server语法:

SELECT s1.Score,
    (SELECT COUNT(DISTINCT s2.Score) FROM Scores s2 WHERE s1.Score <= s2.Score) AS Ranking
FROM Scores s1
ORDER BY s1.Score DESC;

SQL Server不支持以这种方式使用的变量,因此语法不会转换。标量变量由查询设置一次,而不是为结果集的每一行设置一次。MySQL在这里的语法是一种在没有分析函数支持的情况下获得类似于分析函数的行为的攻击。您只需使用:

SELECT Score,
    DENSE_RANK() OVER(ORDER BY Score DESC) AS Rank
FROM Scores
ORDER BY Score DESC;
如果坚持不使用DENSE_RANK,可以使用SQL Server 2000中的SQL Server语法:

SELECT s1.Score,
    (SELECT COUNT(DISTINCT s2.Score) FROM Scores s2 WHERE s1.Score <= s2.Score) AS Ranking
FROM Scores s1
ORDER BY s1.Score DESC;

使用密级。我知道解决方案的其他版本,我只想知道如何将其转换为SQL server版本。特别是如何使用变量,更新SQL server中的变量。您知道解决方案的其他版本是什么意思?如果你知道怎么做,为什么要问?你不需要任何变量。是的,我可以不使用变量来实现它,但我只想知道如何在SQL server中使用变量来实现它,就像MySQL中的代码一样。使用DENSE_RANK。我知道解决方案的其他版本,我只想知道如何将其转换为SQL server版本。特别是如何使用变量,更新SQL server中的变量。您知道解决方案的其他版本是什么意思?如果你知道怎么做,为什么要问?你不需要任何变量。是的,我可以不使用变量来实现它,但我只想知道如何在SQL server中使用变量来实现它,就像MySQL中的代码一样。谢谢你的回复和改进。那么,对于SQL Server,我们只能使用稠密秩函数?我们能自己实现稠密等级吗?顺便说一下,我测试了你的代码,它是不正确的。所有排名都是空的。不@JianZhang,你错了。戈登的密码是正确的。你可以看到。好笑的是,在别人批评了你的原始代码之后,你这么快就声称某人是错的。谢谢你的回复和改进。那么,对于SQL Server,我们只能使用稠密秩函数?我们能自己实现稠密等级吗?顺便说一下,我测试了你的代码,它是不正确的。所有排名都是空的。不@JianZhang,你错了。戈登的密码是正确的。你可以看到。好笑的是,在别人批评了你的原始代码之后,你这么快就声称某人错了。谢谢。SQL Server不支持以这种方式使用的变量,因此语法不会转换。这就是我需要的~谢谢。SQL Server不支持以这种方式使用的变量,因此语法不会转换。这就是我需要的~