0

我有以下要翻译的 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

我花了一个下午的时间摆弄,但我一直遇到 GROUP BY 和聚合的问题以及各种其他错误。

为了在作品中添加更多扳手,排名表没有主键,我认为可能需要让它工作......

服务器版本Microsoft SQL Server 2000 - 8.00.2039

架构

rank_id         int(11)
week_id         int(11)
rider_id        int(11)
year_no         int(11)
rank_no         int(11)
effective_dt    datetime
lastupdate_dt   datetime
point_no        float
average_no      float  
result_qy       int(11)

数据集

INSERT INTO `ranking` (`id`, `rank_id`, `week_id`, `rider_id`, `year_no`, `rank_no`,  `effective_dt`, `lastupdate_dt`, `point_no`, `average_no`,  `result_qy`)
VALUES
(244, 1950, 417, 72253, 2007, 1, '2006-09-03 00:00:00', '2006-09-01 01:45:00', 2559.19, 426.53, 5),
(108, 1950, 426, 72253, 2007, 1, '2006-11-05 00:00:00', '2006-11-01 05:59:00', 2559.19, 426.53, 5),
(340, 1950, 386, 21767, 2006, 1, '2006-01-29 00:00:00', '2006-11-29 13:31:00', 3256.25, 814.06, 4),
(178, 1950, 420, 60369, 2007, 2, '2006-09-24 00:00:00', '2006-09-26 06:31:00', 2315.86, 385.98, 4),
(166, 1950, 417, 60369, 2007, 2, '2006-09-03 00:00:00', '2006-09-01 01:45:00', 2315.86, 385.98, 4),
(109, 1950, 426, 60369, 2007, 2, '2006-11-05 00:00:00', '2006-11-01 05:59:00', 2315.86, 385.98, 4),
(110, 1950, 426, 49428, 2007, 3, '2006-11-05 00:00:00', '2006-11-01 05:59:00', 2191.19, 365.2, 4),
(227, 1950, 417, 49428, 2007, 3, '2006-09-03 00:00:00', '2006-09-01 01:45:00', 2191.19, 365.2, 4),
(409, 1950, 388, 19570, 2006, 3, '2006-02-12 00:00:00', '2006-11-29 13:31:00', 3106.26, 776.57, 4),
(72, 1950, 399, 47036, 2006, 4, '2006-04-30 00:00:00', '2006-11-29 13:33:00', 1038.02, 346.01, 3),
(413, 1950, 388, 55533, 2006, 4, '2006-02-12 00:00:00', '2006-11-29 13:31:00', 2835.3, 708.83, 4),
(111, 1950, 426, 64517, 2007, 4, '2006-11-05 00:00:00', '2006-11-01 05:59:00', 2001.68, 333.61, 4),
(112, 1950, 426, 72379, 2007, 5, '2006-11-05 00:00:00', '2006-11-01 05:59:00', 1677.32, 279.55, 6),
(263, 1950, 420, 27123, 2007, 5, '2006-09-24 00:00:00', '2006-09-26 06:31:00', 1607.31, 267.88, 4),
(415, 1950, 388, 45738, 2006, 5, '2006-02-12 00:00:00', '2006-11-29 13:31:00', 2744.03, 686.01, 4),
(113, 1950, 426, 27123, 2007, 6, '2006-11-05 00:00:00', '2006-11-01 05:59:00', 1607.31, 267.88, 4),
(575, 1950, 420, 50354, 2007, 6, '2006-09-24 00:00:00', '2006-09-26 06:31:00', 1148.84, 191.47, 2),
(422, 1950, 388, 39070, 2006, 6, '2006-02-12 00:00:00', '2006-11-29 13:31:00', 2626.51, 656.63, 4),
(114, 1950, 426, 65745, 2007, 7, '2006-11-05 00:00:00', '2006-11-01 05:59:00', 1576.83, 262.8, 4),
(293, 1950, 388, 42127, 2006, 7, '2006-02-12 00:00:00', '2006-11-29 13:31:00', 2614.46, 653.62, 4),
(576, 1950, 420, 32669, 2007, 7, '2006-09-24 00:00:00', '2006-09-26 06:31:00', 1133.15, 188.86, 2),
(577, 1950, 420, 23242, 2007, 8, '2006-09-24 00:00:00', '2006-09-26 06:31:00', 1107.79, 184.63, 2),
(199, 1950, 420, 60322, 2007, 8, '2006-09-24 00:00:00', '2006-09-26 06:31:00', 1390.22, 231.7, 3),
(115, 1950, 426, 54984, 2007, 8, '2006-11-05 00:00:00', '2006-11-01 05:59:00', 1532.8, 255.47, 3),
(578, 1950, 420, 41116, 2007, 9, '2006-09-24 00:00:00', '2006-09-26 06:31:00', 1096.64, 182.77, 2),
(116, 1950, 426, 72386, 2007, 9, '2006-11-05 00:00:00', '2006-11-01 05:59:00', 1442.49, 240.41, 6),
(74, 1950, 399, 32669, 2006, 9, '2006-04-30 00:00:00', '2006-11-29 13:33:00', 817.64, 272.55, 3),
(818890, 1950, 1167, 77510, 0, 10, '2012-01-13 00:00:00', '2012-01-13 11:11:00', 1464.43, 366.11, 4),
(825706, 1950, 1168, 70324, 0, 10, '2012-01-20 00:00:00', '2012-01-20 11:05:00', 1259.38, 314.85, 2),
(826752, 1950, 1170, 75911, 0, 10, '2012-02-01 00:00:00', '2012-02-01 12:58:00', 1237.95, 309.49, 3);

正确的输出

1950    426     72253   2007    1   2006-11-05 00:00:00  2006-11-01 05:59:00     2559.19    426.53      5
1950    426     60369   2007    2   2006-11-05 00:00:00  2006-11-01 05:59:00     2315.86    385.98      4
1950    426     49428   2007    3   2006-11-05 00:00:00  2006-11-01 05:59:00     2191.19    365.2       4
1950    426     64517   2007    4   2006-11-05 00:00:00  2006-11-01 05:59:00     2001.68    333.61      4
1950    426     72379   2007    5   2006-11-05 00:00:00  2006-11-01 05:59:00     1677.32    279.55      6
1950    426     27123   2007    6   2006-11-05 00:00:00  2006-11-01 05:59:00     1607.31    267.88      4
1950    426     65745   2007    7   2006-11-05 00:00:00  2006-11-01 05:59:00     1576.83    262.8       4
1950    426     54984   2007    8   2006-11-05 00:00:00  2006-11-01 05:59:00     1532.8     255.47      3
1950    426     72386   2007    9   2006-11-05 00:00:00  2006-11-01 05:59:00     1442.49    240.41      6
1950    1170    75911   0       10  2012-02-01 00:00:00  2012-02-01 12:58:00     1237.95    309.49      3
4

3 回答 3

2

SQL Server 2000 及更高版本

根据您的要求,您需要在每个等级中找到最近的生效日期。为此,您需要编写一个子查询,该查询将获取给定排名的最大有效日期,然后将其与行中的日期进行比较以过滤到所需的结果。这适用于 SQL Server 2000 及更高版本的所有版本。

以下查询已在 SQL Server 2000 中进行了测试。

单击此处查看 SQL Fiddle 中的演示

脚本

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;

SQL Server 2005 及更高版本

您需要使用RANK按列对结果进行分区的函数,然后按降序rank_no对每个分区进行排序。每个已排序的分区部分都将被分配一个等级值,例如 1、2、3 等。您只对这些分区组中的第一个等级感兴趣。因此,因此外部 SELECT 将结果过滤为.rank_noeffective_dtrank_num = 1

只有SQL Server 2005 及以上版本才支持RANK函数。

单击此处查看使用 SQL Server 2012 在 SQL Fiddle 中的演示。

脚本:

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;
于 2012-05-02T10:18:17.517 回答
0

我想建议在WHERE子句中使用子查询来获取最大记录effective_dt(假设值在一个 rank_no 内是唯一的,我猜这是一个日期时间):

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
于 2012-05-02T09:33:35.050 回答
0

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

您也可以尝试以下查询。

/*
    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。

于 2012-05-02T10:12:02.660 回答