4

さまざまな列で並べ替えられた結果を吐き出すことができるクエリがありますが、並べ替えられた列で null 値を処理できる必要があります。どんな助けでも大歓迎です。次に例を示します。

Table [People]
Columns [Name], [Birthday] (NULLABLE)

クエリ where@Sortはソートする列を指定する int であり、@pageStartおよび@pageEndは int で、返される結果をクエリに伝えます。(選択した行のみを返すため[RowNum]、CTE にネストされた列を使用しています。他の処理も行われていますが、簡単にするために削除しています。):

;with results as(
SELECT [Name], [Birthday], ROW_NUMBER() OVER  (ORDER BY 
         CASE WHEN @Sort = 0 THEN [Name] END,
         CASE WHEN @Sort = 2 THEN [Birthday] END,
         CASE WHEN @Sort = 1 THEN [Name] END DESC,
         CASE WHEN @Sort = 3 THEN [Birthday] END DESC) AS RowNum
FROM [People]
)
SELECT [Name], [Birthday]
FROM results
WHERE RowNum BETWEEN @pageStart AND @pageEnd
--ORDER RowNum
--The last order by doesn't seem to be needed

null は、次のようなステートメントで処理できることを知っています。

ORDER BY (CASE WHEN [columnName] is NULL THEN 1 ELSE 0 END), [columnName]

作業中のクエリにそれを適用するのに苦労しています...どんな助けも大歓迎です! 何か明確にできることがあれば教えてください。

4

3 に答える 3

2

あなたはほとんどそこにいるようです。ステートメントの代わりに、CASE...WHEN...END代わりに使用できますISNULL()

同じデータ型から関連する値を選択する必要がありますが@Sort = 0、たとえば、

CASE WHEN @Sort = 0 THEN ISNULL([Name], '') END, 

また、一連のCASE...WHEN...ENDステートメントを次のようなものに凝縮できるようです。

CASE @Sort
    WHEN 0 THEN ISNULL([Name], '')
    WHEN 2 THEN ISNULL([Birthday], 0)
...
...
END
于 2012-05-03T12:36:08.177 に答える
1

CASE式でsortパラメーターをnullチェックと組み合わせることができます。

;with results as(
SELECT [Name], [Birthday], ROW_NUMBER() OVER  (ORDER BY 
       CASE WHEN @Sort = 0 AND [Name] IS NULL THEN 1 ELSE 0 END, [Name],
       CASE WHEN @Sort = 2 AND [Birthday] IS NULL THEN 1 ELSE 0 END, [Birthday],
       CASE WHEN @Sort = 1 AND [Name] IS NULL THEN 1 ELSE 0 END, [Name] DESC,
       CASE WHEN @Sort = 3 AND [Birthday] IS NULL THEN 1 ELSE 0 END, [Birthday] DESC)As RowNum
FROM [People]
)
SELECT [Name], [Birthday]
FROM results
WHERE RowNum BETWEEN @pageStart AND @pageEnd
于 2012-05-03T12:36:12.950 に答える
0

あなたのクエリは、コードの再利用に関して優れています。残念ながら、最適化の点でも貧弱です。 (それも本当の言葉ですか?)

この単一のクエリに対して、オプティマイザは単一の実行計画を作成する必要があります。たとえば、順序付けのために異なるインデックスを切り替えることはできません。代わりに、パラメーターが変更されると、データを「手動で」並べ替える必要があります。

これは特にページングに関連しています。適切なインデックスを使用すると、オプティマイザーは範囲シークを使用して、必要な行に直接ジャンプできます。単一のクエリの場合、実際にテーブル全体を処理し、適切に並べ替えてから、適切なレコードにジャンプするという効果があります。 (すべてのパラメーターに適合する 1 つのプランを用意した結果です。) 大量のデータの場合、これは非常に大きなオーバーヘッドです。

このため、動的 SQL を使用してこれにアプローチする方が、実際にははるかにパフォーマンスが高いことがよくあります。これにより、異なる順序ごとに独自の実行計画を持つことができます。そして、各計画ケースは、それらのニーズに最も適したインデックスを使用します。

于 2012-05-03T12:41:27.267 に答える