web-dev-qa-db-ja.com

SELECT INTOでのORDER BYの保持

1つのテーブルからデータを取得して新しいテーブルにコピーするT-SQLクエリがありますが、特定の条件を満たす行のみです。

SELECT VibeFGEvents.* 
INTO VibeFGEventsAfterStudyStart 
FROM VibeFGEvents
LEFT OUTER JOIN VibeFGEventsStudyStart
ON 
    CHARINDEX(REPLACE(REPLACE(REPLACE(logName, 'MyVibe ', ''), ' new laptop', ''), ' old laptop', ''), excelFilename) > 0
    AND VibeFGEventsStudyStart.MIN_TitleInstID <= VibeFGEvents.TitleInstID
    AND VibeFGEventsStudyStart.MIN_WinInstId <= VibeFGEvents.WndInstID
WHERE VibeFGEventsStudyStart.excelFilename IS NOT NULL
ORDER BY VibeFGEvents.id

テーブルを使用するコードはその順序に依存しており、上記のコピーは期待した順序を保持しません。つまり新しいテーブルVibeFGEventsAfterStudyStartの行は、VibeFGEventsAfterStudyStart.idからコピーされたVibeFGEvents.id列で単調に増加しません。

T-SQLでは、VibeFGEventsVibeFGEventsStudyStartからの行の順序をどのように保持できますか?

17
dumbledad

何のために?

ポイントは-テーブル内のデータは順序付けられていません。 SQL Serverでは、テーブルの固有のストレージ順序は、クラスター化インデックス(定義されている場合)の順序です。

データが挿入される順序は基本的に「無関係」です。データがテーブルに書き込まれる瞬間は忘れられます。

そのため、このようなものを入手しても、何も得られません。データを処理するときに順序が必要な場合は、それを取得するselectにorder by句を配置する必要があります。それ以外はランダムです-つまり、データなどの順序は決定されず、変更される可能性があります。

そのため、達成しようとする際に特定の順序を挿入することは意味がありません。

SQL 101:セットには順序がありません。

25
TomTom

これは少し古いことは知っていますが、似たようなことをする必要がありました。 1つのテーブルの内容を別のテーブルに挿入したいのですが、順序はランダムです。 _select top n_とorder by newid()を使用してこれを実行できることがわかりました。 「上位n」がない場合、順序は保持されず、2番目のテーブルには最初と同じ順序の行がありました。ただし、「トップn」では、順序(私の場合はランダム)が保持されました。行数よりも大きい値「n」を使用しました。だから私のクエリは次の行に沿っていました:

_insert Table2 (T2Col1, T2Col2)
  select top 10000 T1Col1, T1Col2
  from Table1
  order by newid()
_
19
Michael

同じ問題に遭遇しましたが、順序を維持する必要がある理由の1つは、ROLLUPを使用して、その列の平均ではなく生データに基づいて加重平均を取得しようとしたときです。たとえば、4つの店舗で販売されたユニット数に基づいて利益の平均を表示したいとしますか?式Profit/#Units = Avgを作成することにより、これを非常に簡単に行うことができます。 GROUP BYにROLLUPを含めて、すべての場所の平均を確認できるようにしました。今、私は「これは良い情報ですが、ベストアベレージが悪い順に表示し、全体をリストの一番下(または一番上)に保ちたい」と考えています。 ROLLUPはこれに失敗するため、別のアプローチをとります。

保持する必要があるシーケンス(順序)に基づいて行番号を作成してみませんか?

    SELECT OrderBy = ROW_NUMBER() OVER(PARTITION BY 'field you want to count' ORDER BY 'field(s) you want to use ORDER BY')
    , VibeFGEvents.*  
    FROM VibeFGEvents
    LEFT OUTER JOIN VibeFGEventsStudyStart
    ON 
        CHARINDEX(REPLACE(REPLACE(REPLACE(logName, 'MyVibe ', ''), ' new laptop', ''), ' old laptop', ''), excelFilename) > 0
        AND VibeFGEventsStudyStart.MIN_TitleInstID <= VibeFGEvents.TitleInstID
        AND VibeFGEventsStudyStart.MIN_WinInstId <= VibeFGEvents.WndInstID
    WHERE VibeFGEventsStudyStart.excelFilename IS NOT NULL

これで、テーブルのOrderByフィールドを使用して値の順序を設定できます。上記のクエリからORDER BYステートメントを削除しました。これは、データがテーブルにロードされる方法に影響しないためです。

0
MHeath

これを望む理由(特定の順序)は、サブクエリで順序を定義できないためです。そのため、テーブル変数を作成し、そのテーブル変数からクエリを作成すると、順序を保持します(たとえば、XMLまたはjsonの順序である必要がある行を連結します)が、できません。それで、あなたは何をしますか?答えは、selectでTOPを使用してSQLに強制的に順序付けすることです(すべての行をカバーするのに十分な数を選択するだけです)。

0
MC9000

ORDER BYでこれを行うことはできませんが、SELECT INTOの後にVibeFGEvents.idでクラスター化インデックスを作成すると、テーブルはVibeFGEvents.idによってディスク上でソートされます。

0
Cyndi Baker