44

ページ付けされたレコードセットにいくつかの繰り返し行があることに気づきました。

このクエリを実行すると:

SELECT "students".* 
FROM "students" 
ORDER BY "students"."status" asc 
LIMIT 3 OFFSET 0

私は得る:

    | id | name  | status |
    | 1  | foo   | active |
    | 12 | alice | active |
    | 4  | bob   | active |

次のクエリ:

SELECT "students".* 
FROM "students" 
ORDER BY "students"."status" asc 
LIMIT 3 OFFSET 3

私は得る:

    | id | name  | status |
    | 1  | foo   | active |
    | 6  | cindy | active |
    | 2  | dylan | active |

両方のクエリに「foo」が表示されるのはなぜですか?

4

3 に答える 3

75

両方のクエリに「foo」が表示されるのはなぜですか?

返されるすべての行の列の値が同じであるためstatusです。その場合、データベースは任意の順序で行を自由に返すことができます。

再現可能な注文が必要な場合は、一貫性を保つために、orderbyステートメントに2番目の列を追加する必要があります。例:ID列:

SELECT students.* 
FROM students 
ORDER BY students.status asc, 
         students.id asc

2つの行のステータス列の値が同じである場合、それらはIDで並べ替えられます。

于 2012-11-27T09:19:38.527 に答える
25

PostgreSQLのドキュメント( http://www.postgresql.org/docs/8.3/static/queries-limit.html )の詳細については:

LIMITを使用する場合は、結果の行を一意の順序に制約するORDERBY句を使用することが重要です。そうしないと、クエリの行の予測できないサブセットが取得されます。10行目から20行目までを求めているかもしれませんが、10行目から20行目はどのような順序ですか?ORDER BYを指定しない限り、順序は不明です。

クエリオプティマイザは、クエリプランを生成するときにLIMITを考慮に入れるため、LIMITとOFFSETに何を指定するかによって、異なるプランを取得する(異なる行の順序を生成する)可能性が非常に高くなります。したがって、異なるLIMIT / OFFSET値を使用してクエリ結果の異なるサブセットを選択すると、ORDER BYを使用して予測可能な結果の順序付けを強制しない限り、一貫性のない結果が得られます。これはバグではありません。これは、順序を制約するためにORDER BYが使用されない限り、SQLが特定の順序でクエリの結果を提供することを約束しないという事実の固有の結果です。

于 2015-06-11T09:13:57.517 に答える
0
select * from(
    Select "students".* 
    from "students" 
    order by "students"."status" asc 
    limit 6
) as temp limit 3 offset 0;
select * from(
    Select "students".* 
    from "students" 
    order by "students"."status" asc 
    limit 6
) as temp limit 3 offset 3;

ここで、6は調査中のレコードの総数です。

于 2021-07-29T08:40:13.767 に答える