0

MSSQL で動作するように翻訳したい次の MySQL クエリがあります。

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関数を使用する必要があります。ソートされた各パーティション セクションには、1、2、3 などのランク値が割り当てられます。これらの各パーティション グループの最初のランクのみが必要です。したがって、外側の SELECT で結果をフィルタリングします。rank_norank_noeffective_dtrank_num = 1

RANK関数は、 SQL Server 2005 以降でのみサポートされています。

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

主キーがない場合、またはこのテーブルにクラスター化されていない場合、データが大きくなると非常に遅くなることに注意してください。どのフィールドがキーであると想定されているかを確認することを真剣にお勧めします。クラスター化インデックスのないテーブルはヒープであり、順序がありません (通常、挿入された順序で格納されます)。

次のクエリも試すことができます。

/*
    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 は CTE をサポートしていないため、これは MySQL では機能しません。

于 2012-05-02T10:12:02.660 に答える
0

WHEREサブクエリ in句を使用して最大のレコードを取得することをお勧めしますeffective_dt(値が 1 つの rank_no 内で一意であると仮定すると、それは datetime であると思います):

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 に答える