如何将使用GROUPBY和ORDERBY子句的MySQL转换为T-SQL查询?

如何将使用GROUPBY和ORDERBY子句的MySQL转换为T-SQL查询?,mysql,group-by,sql-server-2000,sql-order-by,Mysql,Group By,Sql Server 2000,Sql Order By,我想翻译以下MySQL查询,以便在MSSQL中工作: SELECT * FROM ( SELECT * FROM ranking ORDER BY rank_no ASC , effective_dt DESC ) AS sorted_rank WHERE sorted_rank.rank_id = 1950 GROUP BY sorted_rank.rank_no LIMIT 10 我花了

我想翻译以下MySQL查询,以便在MSSQL中工作:

SELECT  *
FROM 
(
    SELECT      *
    FROM        ranking
    ORDER BY    rank_no ASC
            ,   effective_dt DESC
) AS sorted_rank
WHERE       sorted_rank.rank_id = 1950
GROUP BY    sorted_rank.rank_no
LIMIT 10
我花了一个下午的时间来摆弄,但我总是遇到分组和聚合的问题,以及各种各样的错误

为了在工作中添加更多的扳手,排名表没有主键,我认为可能需要它来实现这个工作

服务器版本:Microsoft SQL Server 2000-8.00.2039

模式:

数据集:

正确输出:


我建议使用
WHERE
子句中的子查询来获取具有最大
有效\u dt
的记录(假设值在一个秩内是唯一的,我猜这是一个日期时间):


请注意,如果没有主键或聚集在这个表上,当数据增长时,速度会非常慢。我郑重建议您找出哪些字段应该是键。没有聚集索引的表是一个堆,它们没有顺序(通常按插入顺序存储)

您也可以尝试以下查询

/*
    This CTE will sort the table into a usable structure. To see what it does run the select statement seperately.
*/
;WITH CTERankID
AS
(

SELECT  *
        ,ROW_NUMBER() OVER(PARTITION BY rank_no ORDER BY effective_Dt DESC) AS RowNo        
FROM ranking

)
SELECT  TOP 10   
    rank_id
    ,week_id
    ,year_no
   ,rank_no
   ,effective_dt
   ,lastupdate_dt
   ,point_no
   ,average_no
   ,result_qy
   ,rowno
FROM CTERankID AS rankTable
WHERE rankTable.RowNo=1
AND rankTable.rank_id = 1950
希望这会有点帮助。PS这在MySQL中不起作用,因为MySQL不支持CTE。

SQL Server 2000及更高版本 根据您的要求,您需要在每个级别中查找最近的生效日期。要实现这一点,您需要编写一个子查询来获取给定排名的最大生效日期,然后将其与行中的日期进行比较,以筛选出所需的结果。这将适用于SQL Server 2000及以上版本的所有版本

以下查询已在SQLServer2000中测试

脚本:

SELECT
TOP 10      id 
        ,   rank_id
        ,   week_id
        ,   rider_id 
        ,   year_no
        ,   rank_no
        ,   effective_dt 
        ,   lastupdate_dt 
        ,   point_no  
        ,   average_no 
        ,   result_qy
FROM
(
    SELECT  id 
        ,   rank_id
        ,   week_id
        ,   rider_id 
        ,   year_no
        ,   rank_no
        ,   effective_dt 
        ,   lastupdate_dt 
        ,   point_no  
        ,   average_no 
        ,   result_qy
        ,   RANK() OVER(
                    PARTITION BY rank_no 
                    ORDER BY rank_no, effective_dt DESC) rownum
    FROM    ranking r
    WHERE   r.rank_id = 1950
) t1 
WHERE rownum = 1;
SQL Server 2005及以上版本 您需要使用
RANK
函数,该函数将按
RANK\u no
列对结果进行分区,并按
RANK\u no
对每个分区进行排序,然后按降序排列
effective\u dt
。每个已排序的分区部分将被分配一个秩值,如1、2、3等。您只对每个分区组的第一个秩感兴趣。因此,外部选择通过
rank\u num=1
过滤结果

只有SQL Server 2005及更高版本才支持秩函数

脚本:

SELECT
TOP 10      id 
        ,   rank_id
        ,   week_id
        ,   rider_id 
        ,   year_no
        ,   rank_no
        ,   effective_dt 
        ,   lastupdate_dt 
        ,   point_no  
        ,   average_no 
        ,   result_qy
FROM
(
    SELECT  id 
        ,   rank_id
        ,   week_id
        ,   rider_id 
        ,   year_no
        ,   rank_no
        ,   effective_dt 
        ,   lastupdate_dt 
        ,   point_no  
        ,   average_no 
        ,   result_qy
        ,   RANK() OVER(
                    PARTITION BY rank_no 
                    ORDER BY rank_no, effective_dt DESC) rownum
    FROM    ranking r
    WHERE   r.rank_id = 1950
) t1 
WHERE rownum = 1;

为什么您要按
排名\u no
进行分组?是否要获得某个
排名
字段与同一个
排名_no
字段的总和?请提供
排名
表格结构。排名的值为1,2,3,4等,但每个数字可以出现多次(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4等)。我只希望每个可能的排名都有最新的一行,因此排名表格有哪些列?Andy听起来这是一个更大的问题。没有主键的表可能不是很好的设计。请把表格的定义贴出来好吗。同时也要摆脱MSSQL不支持的限制。你需要做一个前十名。你如何确定最晚的排名?group by没有标识最新排名不,它只是通过将项目1,1,1分组为1来删除重复项。我认为相关的项目在查询中显示,但我已将架构添加到原始帖子中。好的,这不起作用,但我意识到你是在瞎猜——我已经用一个样本数据集和预期输出更新了这个问题。谢谢你花这么多时间!我似乎没有RANK(),这意味着我不在SQL Server 2005上(我意识到我应该提到这一点),除此之外,这个解决方案看起来正是我所需要的!有没有办法解决我没有排名()的问题?请选择@版本。我们的所有解决方案都无法在SQL 2000及以下版本上运行。@Namphibian-Microsoft SQL Server 2000-8.00.2039,非常抱歉最初没有发布这些信息@湿婆你打败了我,我用了简单的行号,但这是一种方法。很高兴看到有人使用SQL rank函数。@Andy您需要认真考虑升级。SQL2000不再受支持,而且由于不再维护,它极易受到攻击。SQL 2000中的查询也将是一个难题。正如我对@Siva的回复一样,我似乎没有ROW_NUMBER(),这意味着我无法使用此解决方案。我不知道SQL Server版本会成为一个问题,或者我会在我最初的问题中提到,我为浪费您的时间感到难过:(
SELECT TOP 10 *
FROM ranking R
WHERE R.rank_id = 1950 AND 
    R.effective_dt = (SELECT MAX(effective_dt) from ranking R2 WHERE R2.rank_no = R.rank_no AND R2.rank_id = R.rank_id)
ORDER BY R.rank_no
/*
    This CTE will sort the table into a usable structure. To see what it does run the select statement seperately.
*/
;WITH CTERankID
AS
(

SELECT  *
        ,ROW_NUMBER() OVER(PARTITION BY rank_no ORDER BY effective_Dt DESC) AS RowNo        
FROM ranking

)
SELECT  TOP 10   
    rank_id
    ,week_id
    ,year_no
   ,rank_no
   ,effective_dt
   ,lastupdate_dt
   ,point_no
   ,average_no
   ,result_qy
   ,rowno
FROM CTERankID AS rankTable
WHERE rankTable.RowNo=1
AND rankTable.rank_id = 1950
SELECT  
TOP 10  id
    ,   rank_id
    ,   week_id
    ,   rider_id 
    ,   year_no
    ,   rank_no
    ,   effective_dt 
    ,   lastupdate_dt 
    ,   point_no  
    ,   average_no 
    ,   result_qy
FROM    ranking r_outer
WHERE   rank_id = 1950
AND     effective_dt = 
        (
            SELECT  MAX(effective_dt)
            FROM    ranking r_inner
            WHERE   r_inner.rank_no = r_outer.rank_no
            AND     r_inner.rank_id = 1950
        )
ORDER BY rank_no;
SELECT
TOP 10      id 
        ,   rank_id
        ,   week_id
        ,   rider_id 
        ,   year_no
        ,   rank_no
        ,   effective_dt 
        ,   lastupdate_dt 
        ,   point_no  
        ,   average_no 
        ,   result_qy
FROM
(
    SELECT  id 
        ,   rank_id
        ,   week_id
        ,   rider_id 
        ,   year_no
        ,   rank_no
        ,   effective_dt 
        ,   lastupdate_dt 
        ,   point_no  
        ,   average_no 
        ,   result_qy
        ,   RANK() OVER(
                    PARTITION BY rank_no 
                    ORDER BY rank_no, effective_dt DESC) rownum
    FROM    ranking r
    WHERE   r.rank_id = 1950
) t1 
WHERE rownum = 1;