SQL Server2005でのSelectした時のレコードの取得順について

このQ&Aのポイント
  • SQL Server2005でデータの取得順を理解するためには、ORDER BY句の動作を把握する必要があります。ORDER BY句は、指定したカラムや式に基づいてレコードを並び替えるためのものです。同じ値を持つ複数のレコードが存在する場合、その順番は保証されません。
  • 例えば、SELECT文にORDER BY句を含めずにレコードを取得する場合、レコードの並び順はデータが格納された順序に依存します。つまり、INSERT文の実行順や物理的なディスク上の配置によってレコードの取得順が決まります。
  • 一方、ORDER BY句を使用してレコードを並び替える場合、指定したカラムに基づいてレコードがソートされます。同じ値を持つカラムが複数ある場合は、その次に指定したカラムでソートされます。また、同じ値を持つ場合には保証された順序でレコードが取得されます。
回答を見る
  • ベストアンサー

Selectした時のレコードの取得順

SQL Server2005 で開発しています。 Order by で並び替えてレコードをSelectする際に、 Order by の対象列データが同じ場合は、 どういった順番でレコードが取得できるのでしょうか? TableA No | Data1 | Data2   1| AAA | 100   2| AAA | 200   3| AAA | 300   4| ABC | 400   5| BBB | 500 (Noはクラスタ化PK) 例えば、上のようなテーブルから次のSQLを実行すると  (1)Select * From TableA ;  (2)Select * From TableA Order by Data1 Asc;  (3)Select * From TableA Order by Data1 Asc, No Asc;  (1)(2)(3)全て、次の順で返ってきました。   1| AAA | 100   2| AAA | 200   3| AAA | 300   4| ABC | 400   5| BBB | 500  しかし、(2)のSQLは、データによって  次の順で返ってくることがありました。   3| AAA | 300   1| AAA | 100   2| AAA | 200   4| ABC | 400   5| BBB | 500    1~3レコード目までは全てData1がAAAのレコードですが  特に指定していなくても、No(PK)の順になるのかと思っていました。    なお、レコードができた(Insert順)でもなさそうです。  この、順番は何で決まっているのでしょうか?  

質問者が選んだベストアンサー

  • ベストアンサー
  • hogya
  • ベストアンサー率67% (49/73)
回答No.2

>特に指定していなくても、No(PK)の順になるのかと思っていました。 下記のリンクに「ORDER BY 句が指定されていない限り、結果セットとして返される行の順序は保証されません。」と書いてあるので実際、保証されていないのだと思います。 http://msdn.microsoft.com/ja-jp/library/ms188385.aspx で、実際にどういう順番で返ってくるのかはインデックスの種類(クラスタかどうかなど)や設定状況によって変わってくるのでケースバイケースだと思います。

hi3-5-0
質問者

お礼

ありがとうございます。 リンク先の↓を見て、すっきりしました。 「ORDER BY 句が指定されていない限り、結果セットとして返される行の順序は保証されません。」

その他の回答 (2)

  • nora1962
  • ベストアンサー率60% (431/717)
回答No.3

ソートアルゴリズムを勉強すれば分かりますが、ほとんどのソートアルゴリズムはキーで指定された以外のデータ順については保障がありません。(安定的なソートではない)。 また、RDBMSが仮に安定的なソートアルゴリズムであっても、どのような順序にデータをフェッチするかはRDBMSの実装に依存しています。 > この、順番は何で決まっているのでしょうか? きまりはないと思ってください。

hi3-5-0
質問者

お礼

ありがとうございます。

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

SQL Serverのローカルルールはよくわかりませんが たいていのSQLではORDER BYで明示されていない場合は 表示順序は保障されない(つまり何順かわからない) というのが原則だと思います どうしても確定した表示が必要であれば、なんらかの ユニークな属性のついたカラムでorder byしてやることです

hi3-5-0
質問者

お礼

ありがとうございます。

関連するQ&A

  • SELECT FOR UPDATE で該当レコードがなかった場合

    SELECT FOR UPDATE ですが、該当レコードのみ ロックすると思うんですが、 該当レコードがない場合は、 ロックできないんでしょうか? たとえば、(COLUMN_BBB が PK として) SELECT * FROM TABLE_AAA WHERE TABLE_AAA.COLUMN_BBB = 'BBB' FOR UPDATE で、そもそも SELECT * FROM TABLE_AAA WHERE TABLE_AAA.COLUMN_BBB = 'BBB' となるレコードがない場合でも、 他トランザクションによる 該当レコードの INSERT を排他防御できるのか無理なのか、 教えていただけたらありがたいです。 すみません、時間的余裕があまりないので、 (すぐに回答ほしいです)でアップします。

  • 重複レコードの抽出について

    以下のようなテーブルからmailが重複していてnameの値が全て同じ値を持つレコードを取得するためのSQL文を教えてください。 mail | name ----------- aaa | 01 aaa | 01 aaa | 01 bbb | 02 bbb | 02 bbb | 01 ccc | 01 ccc | 01 ccc | 02 select * from test where mail in (select mail from test where mail group by mail having count(mail)>1) 上記のSQL文だと以下のデータが取得されてしまいます。 ↓ mail | name ----------- aaa | 01 ○ aaa | 01 ○ aaa | 01 ○ bbb | 02 × bbb | 02 × ccc | 01 × ccc | 01 × ○印のみ取得したいのですが、 SQL文をどのように修正すればよいのでしょうか。 よろしくお願いいたします。

  • 日付の最大値レコードを取得する方法について

    お世話になります。 SQLで日付の最大値を取得する方法です。 テーブルのデータ内容は以下のようになっています。 | 社員番号 | 社員名 | 日付 | 順序 | +---------+-------+-----------+-----+ | 100 | AAA | 2011/05/01 | 2 |   ← このレコードを取得したい +---------+-------+-----------+-----+ | 100 | AAA | 2011/05/01 | 1 | +---------+-------+-----------+-----+ | 100 | AAA | 2011/04/01 | 1 | +---------+-------+-----------+-----+ | 200 | BBB | 2011/04/01 | 2 |   ← このレコードを取得したい +---------+-------+-----------+-----+ | 200 | BBB | 2011/04/01 | 1 | +---------+-------+-----------+-----+ 取得したいレコードは、 社員ごとの最大日付の最大順序をもつレコードです。 (上記の1行目と4行目のレコードを取得したい) この場合、 下記のようなSQLを考えます。 --------------------------------- SELECT 社員番号, 社員名, 日付 FROM テーブル名 WHERE 社員番号 = 'xxx' AND 日付 = (SELECT MAX(日付) FROM テーブル名 ) AND 順序 = (SELECT MAX(順序) FROM テーブル名 ) ---------------------------------- 但し、上記の場合、 社員ごとに最大値レコードが取得できません。 どなたかレコード取得方法について 教えていただけないでしょうか? よろしくお願いいたします。

  • select文の表示結果を置き換える

    sql初心者です、皆様ご教授お願いいたします。 以下のようなselect文の結果が・・・ select aaa,bbb,ccc from XXX order by aaa 以下のようになった場合・・・ 埼玉 100 AAA 東京 200 BBB 東京 200 CCC 東京 300 CCC 千葉 400 CCC 以下のような表示を行う事はsqlで可能でしょうか? 埼玉 100 AAA 東京 200 BBB (〃)(〃) CCC (〃) 300 (〃) 千葉 400 (〃) つまり「一つ前のレコードと同じ結果だった項目は”〃”等の任意の文字列を出力する」です。 宜しくお願いいたします。

  • PHP SQL 問合せについて

    PHP SQL 問合せについて http://okwave.jp/qa/q7689206.html での質問の続きとなります。 No,name 1,ばなな 2,りんご 3,ばなな 4,みかん 5,ばなな 6,りんご 上記テーブルで 1,ばなな 3,ばなな 5,ばなな 2,りんご 6,りんご 4,みかん の結果を得るSQLはどのように記述すればよいでしょうか? 回答 select * from tableA x order by (select count(*) from tableA y where y.name = x.name ) ,No で解決していますが、 select * from tableA x where name ='果物' とした場合、結果が異なります。 (結果が多い順にならない) 出現回数が多い順に並べるには、どのような記述になりますか? データには「果物以外のデータが含まれている」とします。 宜しくお願い致します。

    • 締切済み
    • PHP
  • 重複データからの取得方法を教えてください

    id s_no s_name ---------------- 1 001 aaaa 2 005 bbb1 3 005 bbb2 4 002 cccc 5 005 bbb3 6 005 bbb4 上のものがテーブルの内容です。取得したい結果が ---------------- 1 001 aaaa 4 002 cccc 5 005 bbb3 です。 試したSQLは select distinkd on (s_no) id,s_name from shain where id>=5 order by id desc select id,s_no,s_name from shain where id>=5 group by s_no order by id desc などです。 データベースがmdbなのでdistinkd onは使えませんでした。 もしかすると書式が違うのでしょうか?

  • レコードの1番目のみselectする方法

    select * from table_test order by table_test_update; 表:table_test 列:table_test_update・・・更新日 レコードセット数:123 多数のレコードの内の1番目のレコードのみのレコードセットを作成(選択(select))したいのですが、 どのようにSQL文を作成すればいいのでしょうか? 宜しくお願いいたします

  • SQLとDAOで取得するレコード件数が違う?

    Access2007でSQLで実行した結果と、レコードセットで取得した件数が一致せずに困っています。 いろいろ調べてはみたのですが、なぜかわかりません。 よろしくお願いします。 ○TableA 型 Code1 数値型(主キー) Text テキスト型 Code2 数値型 ○TableA データ Code1 Text Code2 111 AAA 10 112 BBB 15 113 CCC 20 114 DDD 20 ○VBAコード Dim strSQL As String Dim db As DAO.Database Dim rstFind As DAO.Recordset strSQL = "SELECT * FROM TableA Where Code2 = 20" Set db = CurrentDb() Set rstFind = db.OpenRecordset(strSQL, dbOpenSnapshot) MsgBox rstFind.RecordCount この状態でSQLビューから実行すると2件が抽出され、上記VBAを実行するとMsgBoxには「1」と表示されます。

  • 五十音順

    テーブルのフィールドに、読み仮名が入っています。 あ行、か行など、五十音順に抽出する場合のSQL文ですが、 $sql = 'select * from テーブル名 where kana between "あ" and "お" order by kana'; 上記の文を $sql = 'select * from テーブル名 where kana between "$key[$i]" order by kana'; という具合に配列などに入れたいと考えておりますが。 そのようなことは可能なのでしょうか? それとも、もっと効率よく五十音順の検索ができるようにする方法が ありますでしょうか?

  • ソートしてからグループ化したいけれど・・・。

    SQL構文について質問させて下さい。 ABC │ID │DATE ------------------ XXX │aaa │02/01 YYY │bbb │02/02 YYY │aaa │02/03 と言うデータから、DATEが新しい(大きい)値を抽出し、 次に重複するIDを排除した結果を出したいです。 希望の検索結果は、 ABC │ID │DATE ------------------ YYY │bbb │02/02 YYY │aaa │02/03 となって欲しいのです。 単純にソートした後でIDでグループ化したいのですが、当然できなく、私の考えでは、 SELECT abc, id, max( date ) FROM `test` GROUP BY id ORDER BY date DESC なのですが結果は、 ABC │ID │DATE ------------------ YYY │bbb │02/02 XXX │aaa │02/03 と言う風になり、何故か、2行目の様にDATEに対して、ABCの値が別の行の ID:aaaの値になってしまってます。 どうしたら良いのでしょうか?

    • ベストアンサー
    • MySQL