1

データを含むテーブル変数があります:

SiteID  DatabaseYear  CreationDate
1       2011          2012.01.01
2       2012          2012.06.06
3       2010          2010.10.10
1       2012          2012.07.07
3       2012          2012.07.27
4       2012          2012.08.31

完璧な世界では、次のように結果を並べ替えたいと思います。

SiteID  DatabaseYear  CreationDate
4       2012          2012.08.31
3       2012          2012.07.27
3       2010          2010.10.10
1       2012          2012.07.07
1       2011          2012.01.01
2       2012          2012.06.06

並べ替えは次のようになります。最新の作成日を持つサイトを取得して最初に表示し(CreationDate descで並べ替え)、次にそのサイトの他のすべてのレコードを取得してDatabaseYearで表示します(DatabaseYear descで並べ替え)。

もちろん、以下はまったく機能しません。

order by CreationDate desc, DatabaseYear desc

最初に結果セット全体に「CreationDatedesc」を適用し、次に「DatabaseYeardesc」を適用するためです。

だから、私は次のことをするカーソルを思いついた:

  1. 最新のSiteIDを取得します
  2. 別のテーブルに配置します(正確にはテーブル変数)
  3. DatabaseYearの降順で、そのSiteIDの他のすべてのレコードを取得します
  4. そのためのすべてのレコードを最初のテーブルから削除します

問題:

このロジックは、最初のテーブルに数千のレコードがある場合はうまく機能しますが、5000を超える場合は、さらに時間がかかります。これはWebページにグリッドを配置しているため、ユーザーを15〜20秒以上待たせる余裕はありません。最悪のシナリオ(40,000レコードを超える)では、実行に2〜3分かかります。

任意の提案をいただければ幸いです。

4

2 に答える 2

2

セットの観点からもっと考える必要があります。カーソルが正しい答えになることはほとんどありません。あなたは命令型プログラマーの方針に沿ってもっと考えているようです。

これは、最初に表示されるよりもはるかに簡単に実行できます。

WITH Most_Recent_Site (siteId, createdOn) as (SELECT id, MAX(createdOn)
                                              FROM Site_Data
                                              GROUP BY id)

SELECT Site_Data.id, Site_Data.createdOn
FROM Site_Data
JOIN Most_Recent_Site
ON Most_Recent_Site.siteId = Site_Data.id
ORDER BY Most_Recent_Site.createdOn DESC, Site_Data.createdOn DESC

「データベース年」列は、値を追加していないように見えたため、意図的に省略しました。

(そして、SQL Fiddleの実例があります。)

于 2012-08-06T15:43:13.653 に答える
1
DECLARE @t TABLE  
(
  SiteID INT,  
  DatabaseYear INT,  
  CreationDate DATE
);

INSERT @t VALUES
(1,2011,'2012-01-01'),
(2,2012,'2012-06-06'),
(3,2010,'2010-10-10'),
(1,2012,'2012-07-07'),
(3,2012,'2012-07-27'),
(4,2012,'2012-08-31');

;WITH x AS 
(
  SELECT SiteID, d = MAX(CreationDate) 
     FROM @t
     GROUP BY SiteID
)
SELECT t.SiteID, t.DatabaseYear, t.CreationDate 
FROM @t AS t
INNER JOIN x 
ON t.SiteID = x.SiteID
ORDER BY x.d DESC, t.CreationDate DESC;
于 2012-08-06T15:34:19.673 に答える