2016-03-22 28 views
1

私は125kレコードのテーブルを持っています。毎日、〜20レコードを挿入し、挿入時間順のテーブルの上位1,000レコードに基づいて1,000の通知を生成します。通知が生成されると、通知はマークされ、今後の通知配信のために考慮されなくなります。これは、奇妙な方法で注文された100kの大きなインサートがいくつかの問題を引き起こすことを除いて、長い間うまく働いています。SQL Server 2012の比例ソート

4種類のレコードがあり、2つの異なる値を持つ2つの列があり、これらの4つの型のどちらを決定します。ファイルソートに基づいて、タイプの1つが最初の80kレコードにあり、毎日の通知を支配します。

私はこれを修正するために、挿入時にトリガーを作成して、毎日より均等に通知が分散されるようにテーブルを並べ替えます。

私の質問:列内のデータに基づいて比例的にソートできるSQLソート機能はありますか?

つまり、A列に基づいて80/20の分割を得ることはできますか、B列に基づいて80/20分割を得ることができるので、以下のオプションがある場合、640レコードに(1,1)、 640(1,1)のレコードを持っていない時があるので、ハードコーディングされたselect top Xステートメントを使わずに(1,2)の160レコード、(2,1)の160レコード、(2,2)レコードが、私は1000の合計通知が生成されます。

Column A Column B 
1   1 
1   2 
2   1 
2   2 
+0

テーブルには「オーダー」がありません。あなたがテーブルの中でいくつかの偶発的な注文に頼っているなら、あなたは重大な間違いをしている。結果セットにオーダーしたい場合は、 'ORDER BY'節を使い、そのオーダーを指定する必要があります。 –

+0

私は、 'top'と' union'を使って動的ステートメントを構築することをお勧めします。この方法で、あなたは常に1000の結果を得るでしょう。 –

+0

また、テーブル構造も含めてください。タイプの1つが短い行である場合のルールは何ですか?あなたは特定の他のタイプからそれらをつかみますか?置換行に使用する型の順序は何ですか? –

答えて

2

あなたはあなたが望むものを達成するためにROW_NUMBERを使用できるはずです。あなたは、テーブル構造を提供しなかったので、このうちのいくつかは当て推量です:

;WITH CTE_NumberedRows AS 
(
    SELECT 
     id, 
     column_a, 
     column_b, 
     some_date, 
     ROW_NUMBER() OVER (PARTITION BY column_a, column_b ORDER BY some_date) AS row_num 
    FROM 
     My_Table 
) 
SELECT TOP 1000 
    id, 
    column_a, 
    column_b 
FROM 
    CTE_NumberedRows 
ORDER BY 
    CASE WHEN column_a = 1 AND column_b = 1 AND row_num <= 640 THEN 0 ELSE 1 END, 
    CASE WHEN column_a = 1 AND column_b = 2 AND row_num <= 160 THEN 0 ELSE 1 END, 
    CASE WHEN column_a = 2 AND column_b = 1 AND row_num <= 160 THEN 0 ELSE 1 END, 
    CASE WHEN column_a = 2 AND column_b = 2 AND row_num <= 40 THEN 0 ELSE 1 END, 
    some_date 

あなたがASCまたはDESCために、日付ごとに注文する必要がかどうかは明らかではない(または、あなたも上注文している場合日付を記入してください。)うまくいけばそれができる方法の一般的な要点は十分です。各タイプの最初の "x"行に優先順位を付ける(ORDER BYおよびCASEステートメントを使用)。

+1

私はカラム名とテーブル名で更新することができましたが、これは完全に機能しました。おそらく少し更新されますが、これは素晴らしいことです。ありがとうございました – rdbradshaw

関連する問題