1

Oracleで注文せずに結果を得るための解決策はありますか? これは、次のようにクエリを実行すると、自動的に ID フィールドでソートするのに役立つように見えるためです。

SELECT ID FROM USER WHERE ID IN (5004, 5003, 5005, 5002, 5008);


Actual results          Expected results
---5002                 ---5004
---5003                 ---5003
---5004                 ---5005
---5005                 ---5002
---5008                 ---5008

これに関する解決策があれば、何百万も感謝します。

4

6 に答える 6

5

SELECTステートメントは、句を指定しない限り、予測できない順序で結果セットの行を返します。ORDER BY

特定の DBMS 製品では、結果セットが予測可能な順序になっているように見えます。しかし、これに頼ると必ず裏切られます。

于 2013-02-26T13:39:45.533 に答える
5

これは、私が過去に使用した 1 つの方法ですINSTR

SELECT *
FROM YourTable
WHERE ID IN (5004, 5003, 5005, 5002, 5008)
ORDER BY INSTR ('5004,5003,5005,5002,5008', id)

SQL フィドルのデモ

私はまた、CASEこのような使用を見てきました:

ORDER BY
  CASE ID 
    WHEN 5004 THEN 1   
    WHEN 5003 THEN 2   
    WHEN 5005 THEN 3   
    WHEN 5002 THEN 4   
    WHEN 5008 THEN 5
  END 
于 2013-02-26T13:38:10.850 に答える
1

リスト内の順序を維持したい場合は、次のようにすることができます。

SQL> create type user_va as varray(1000) of number;
  2  /

Type created.

SQL> with users as (select /*+ cardinality(a, 10) */ rownum r, a.column_value user_id
  2                   from table(user_va(11, 0, 19, 5)) a)
  3  select d.user_id, d.username
  4    from dba_users d
  5         inner join users u
  6                 on u.user_id = d.user_id
  7   order by u.r
  8  /

   USER_ID USERNAME
---------- ------------------------------
        11 OUTLN
         0 SYS
        19 DIP
         5 SYSTEM

つまり、要素を varray に入れ、セットをマージする前に rownum を割り当てます。rそれによって、リスト内の順序を維持することができます。ヒントは、オプティマイザーに配列内の行数を伝えるだけです(cardinality大まかに言えば、デッドオンである必要はありません。これがないと、8k 行が想定され、インデックス アプローチよりもフル スキャンが優先される場合があります)。

タイプを作成する特権がなく、これがアドホックなものである場合は、いくつかのパブリックなものがあります。

select owner, type_name, upper_bound max_elements, length max_size, elem_type_name
  from all_Coll_types
 where coll_type = 'VARYING ARRAY' 
and elem_type_name in ('INTEGER', 'NUMBER');
于 2013-02-26T13:45:00.043 に答える
0

ORDER BY 句がないと、並べ替え順序は保証されません。

于 2013-02-26T13:37:54.377 に答える
0

ここで見つけた別の解決策。

select ID 
    from USER 
where ID in (5004, 5003, 5005, 5002, 5008)
    order by decode(ID, 5002, 1, 5003, 2, 5004, 3, 5005, 4, 5008, 5);

デコード順(COLUMN NAME, VALUE, POSITION)

*注: 値と位置のみを繰り返す必要があります

そして、ええ、すべての応答に感謝します! 本当に感謝しています。

于 2013-03-05T02:18:05.727 に答える
0

順序付けが行われる理由に関する質問の場合、答えは次のとおりです。列 ID にインデックスまたは主キーが定義されていますか? はいの場合、データベースはインデックス スキャンでクエリに応答します。つまり、テーブル自体ではなく、ID 列で定義されたインデックスで IN 句の ID を検索します。インデックス内で、値は順序付けられます。

クエリの実行に関する詳細情報を取得するには、Oracle の Explain Plan 機能を試してください。

特定の順序で値を取得するには、ORDER BY 句を追加する必要があります。これを行う1つの方法は

    select ID 
      from USER 
     where ID in (5004, 5003, 5005, 5002, 5008)
     order by
           case ID
             when 5004 then 1
             when 5003 then 2
             ...
           end;

より一般的な方法は、テーブルに ORDERING 列を追加することです。

    select ID 
      from USER 
     where ID in (5004, 5003, 5005, 5002, 5008)
     order by
           ORDERING;
于 2013-02-26T16:01:10.380 に答える