【问题标题】:Postgresql order by out of orderPostgresql order by 乱序
【发布时间】:2021-05-28 21:10:21
【问题描述】:

我有一个数据库,我需要按照与表中填充的顺序相同的顺序检索数据。表名是圣经当我在 psql 中输入table bible; 时,它会按照填充顺序打印数据,但是当我尝试检索它时,某些行总是乱序的,如下例所示:

table bible

-[ RECORD 1 ]-----------------------------------------------------------------------------------------------------------------------------------------
id      | 1
day     | 1
book    | Genesis
chapter | 1
verse   | 1
text    | In the beginning God created the heavens and the earth.
link    | https://api.biblia.com/v1/bible/content/asv.txt.txt?passage=Genesis1.1&key=dc5e2d416f46150bf6ceb21d884b644f
-[ RECORD 2 ]-----------------------------------------------------------------------------------------------------------------------------------------
id      | 2
day     | 1
book    | John
chapter | 1
verse   | 1
text    | In the beginning was the Word, and the Word was with God, and the Word was God.
link    | https://api.biblia.com/v1/bible/content/asv.txt.txt?passage=John1.1&key=dc5e2d416f46150bf6ceb21d884b644f
-[ RECORD 3 ]-----------------------------------------------------------------------------------------------------------------------------------------
id      | 3
day     | 1
book    | John
chapter | 1
verse   | 2
text    | The same was in the beginning with God.
link    | https://api.biblia.com/v1/bible/content/asv.txt.txt?passage=John1.2&key=dc5e2d416f46150bf6ceb21d884b644f

一切都井井有条,但是当我尝试使用例如select * from bible where day='1'select * from bible where day='1' order by dayselect * from bible where day='1' order by day, id; 查询相同的内容时,我总是在选择的那一天(此处为 1)中出现一些乱序的行或其他任何一天。 我一直在使用 Django 来干扰 Postgres 数据库,但是自从我发现这个问题后,我尝试使用 SQL 进行查询,但是什么也没有,我仍然得到乱序的行,尽管它们都有唯一的 ID,我用 select count(distinct id), count(id) from bible;

- [ RECORD 1 ]------------------------------------------------------------------------------------------------------
id      | 1
day     | 1
book    | Genesis
chapter | 1
verse   | 1
text    | In the beginning God created the heavens and the earth.
link    | https://api.biblia.com/v1/bible/content/asv.txt.txt?passage=Genesis1.1&key=dc5e2d416f46150bf6ceb21d884b644f
-[ RECORD 2 ]-----------------------------------------------------------------------------------------------------------------------------------------
id      | 10
day     | 1
book    | Colossians
chapter | 1
verse   | 18
text    | And he is the head of the body, the church: who is the beginning, the firstborn from the dead; that in all things he might have the preemine
nce.
link    | https://api.biblia.com/v1/bible/content/asv.txt.txt?passage=Colossians1.18&key=dc5e2d416f46150bf6ceb21d884b644f
-[ RECORD 3 ]-----------------------------------------------------------------------------------------------------------------------------------------
id      | 11
day     | 1
book    | Genesis
chapter | 1
verse   | 2
text    | And the earth was waste and void; and darkness was upon the face of the deep: and the Spirit of God moved upon the face of the waters.
link    | https://api.biblia.com/v1/bible/content/asv.txt.txt?passage=Genesis1.2&key=dc5e2d416f46150bf6ceb21d884b644f

正如您在上面看到的,如果您注意到,ID 的顺序是 1、10、11。

我的桌子

                              Table "public.bible";
Column  | Type | Collation | Nullable | Default | Storage  | Stats target | Description 
---------+------+-----------+----------+---------+----------+--------------+-------------
id      | text |           |          |         | extended |              | 
day     | text |           |          |         | extended |              | 
book    | text |           |          |         | extended |              | 
chapter | text |           |          |         | extended |              | 
verse   | text |           |          |         | extended |              | 
text    | text |           |          |         | extended |              | 
link    | text |           |          |         | extended |              | 
Access method: heap

id 字段是文本类型,因为我使用 pandas 的 to_sql() 方法来填充圣经表。我尝试删除 id 列,然后使用 ALTER TABLE bible ADD COLUMN id SERIAL PRIMARY KEY; 再次将其添加为 PK,但我仍然无法正常返回数据。

无论如何,我是否可以通过 id 排序来检索数据,而不会使某些行完全乱序?提前谢谢!

【问题讨论】:

  • 你有索引吗?
  • @sddk 啊,没有索引

标签: sql django database postgresql psql


【解决方案1】:

您应该将cast thy id 转换为整数以将其排序为数字。

SELECT * FROM bible ORDER BY cast(id AS integer);

【讨论】:

    【解决方案2】:

    虽然@jordanvrtanoski 是正确的,但使用 django 的方法是:

    >>> Bible.objects.extra(select={'id': 'CAST(id AS INTEGER)'}).order_by('id').values('id')
    <QuerySet [{'id': 1}, {'id': 2}, {'id': 3}, {'id': 10}, {'id': 20}]>
    

    旁注:如果你想过滤 day 作为例子,你可以这样做:

    >>> Bible.objects.extra(select={
        'id': 'CAST(id AS INTEGER)', 
        'day': 'CAST(day AS INTEGER)'}
    ).order_by('id').values('id', 'day').filter(day=2)
    <QuerySet [{'id': 2, 'day': 2}, {'id': 10, 'day': 2}, {'id': 11, 'day': 2}, {'id': 20, 'day': 2}]>
    

    否则你会遇到这个问题:(注意1 后面是10 而不是2

    >>> Bible.objects.order_by('id').values('id')
    <QuerySet [{'id': '1'}, {'id': '10'}, {'id': '2'}, {'id': '20'}, {'id': '3'}]>
    

    我强烈建议你 不要 做任何这些,并正确设置你的表(有正确的列类型,而不是像text ),否则您的查询性能会很糟糕.. BIG TIME

    【讨论】:

    • 感谢您的回复!然而,我在对象上使用过滤器,就像在 SQL 行(...WHERE day='1')中一样,所以当我尝试将额外的方法附加到过滤器结果时,我得到了一个 ids 对象的查询集,就像你的第二个代码 sn-p 一样,你知道有一种方法可以在 Bible.objects.filter(day=1).extra 上应用你的 select 方法吗?非常感谢
    • 我已经编辑了您的答案,因此查询集返回有序对象,就像 SQL 等价一样。感谢您的@Javier Buzzi
    • 我已经设法按照您的示例使其工作;最后是Bible.objects.filter(day=day).extra({ 'id':"CAST(id as INTEGER)"}).order_by('id')
    • 我已经删除了我在帖子中提到的文本 ID,并用整数 PK 替换它们,但由于某种原因,它们仍然被乱序返回,有什么想法吗,先生?跨度>
    • 啊,对不起,我已经发布了一个答案,你是对的,干扰的是我在模型上设置的一个 id 字段,其中 primary_key=True,它会引发错误,例如“id is ambiguous”,所以我只是删除了 id(我通过尝试修复错误忘记了它),进行了迁移,一切都很好,我现在也不依赖 Django 的额外方法,因为正如你所提到的,这不是最好的事情,所以我将表上的 id 字段转换为 INTEGER。谢谢你的帮助!!
    【解决方案3】:

    基于@jordanvrtanoski 和@Javier Buzzi 的两个答案以及一些在线搜索,问题是因为 id 的类型是 TEXT(或 VARCHAR 也是),因此,您需要将 id 转换为 INTEGER 类型,如以下:

    ALTER TABLE bible ALTER COLUMN id TYPE integer USING (id::integer);

    现在这是我的桌子

                                                    Table "public.bible"
    Column  |  Type   | Collation | Nullable |                 Default                 | Storage  | Stats target | Description 
    ---------+---------+-----------+----------+-----------------------------------------+----------+--------------+-------------
    id      | integer |           |          | nextval('bible_id_seq'::regclass) | plain    |              | 
    day     | text    |           |          |                                         | extended |              | 
    book    | text    |           |          |                                         | extended |              | 
    chapter | text    |           |          |                                         | extended |              | 
    verse   | text    |           |          |                                         | extended |              | 
    text    | text    |           |          |                                         | extended |              | 
    link    | text    |           |          |                                         | extended |              | 
    Indexes:
        "lesson_unique_id" UNIQUE CONSTRAINT, btree (id)
    Referenced by:
        TABLE "notes_note" CONSTRAINT "notes_note_verse_id_5586a4bf_fk" FOREIGN KEY (verse_id) REFERENCES days_lesson(id) DEFERRABLE INITIALLY DEFERRED
    Access method: heap
    

    希望这对其他人有所帮助,谢谢大家!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-07
      • 1970-01-01
      • 2014-09-14
      • 2014-03-30
      • 2018-03-20
      • 2018-03-15
      • 2013-01-16
      相关资源
      最近更新 更多