代码之家  ›  专栏  ›  技术社区  ›  theGtknerd

将PostgreSQL列强制转换为存储类型

  •  0
  • theGtknerd  · 技术社区  · 6 年前

    我正在创建PostgreSQL的查看器。我的SQL需要对该列的正常类型进行排序。例如:

    表:

    CREATE TABLE contacts (id serial primary key, name varchar)
    

    SQL:

    SELECT id::text FROM contacts ORDER BY id;
    

    给予:

    1
    10
    100
    2
    

    好的,所以我将SQL更改为:

    SELECT id::text FROM contacts ORDER BY id::regtype;
    

    可用于:

    1
    2
    10
    100
    

    好极了!但现在我试着:

    SELECT name::text FROM contacts ORDER BY name::regtype;
    

    结果是:

    invalid type name "my first string"
    

    谷歌没有帮助。有什么想法吗?谢谢

    重复 :错误不是我的问题。我的问题是我需要将每个列转换为 text ,但按该列的常规类型排序。

    2 回复  |  直到 6 年前
        1
  •  2
  •   klin    6 年前

    regtype 是一个 object identifier type 当您不引用系统对象(本例中的类型)时,没有理由使用它。

    您应该将列强制转换为 integer 在第一个查询中:

    SELECT id::text 
    FROM contacts 
    ORDER BY id::integer;
    

    您可以在 order by 条款。这将适用于任何可排序的列类型。

    SELECT id::text
    FROM contacts 
    ORDER BY contacts.id;
    
        2
  •  1
  •   theGtknerd    6 年前

    所以,我找到了两种方法来实现这一点。第一个是@klin提供的解决方案,它先查询表,然后根据数据构建自己的查询。未测试的psycopg2示例:

    c = conn.cursor()
    c.execute("SELECT * FROM contacts LIMIT 1")
    select_sql = "SELECT "
    for row in c.description:
        if row.name == "my_sort_column":
            if row.type_code == 23:
                sort_by_sql = row.name + "::integer "
            else:
                sort_by_sql = row.name + "::text "
    c.execute("SELECT * FROM contacts " + sort_by_sql)
    

    一个更优雅的方式是这样:

    SELECT id::text AS _id, name::text AS _name AS n FROM contacts ORDER BY id
    

    它使用别名以便 ORDER BY 仍然可以提取原始数据。如果没有其他选项,最后一个选项的可读性更高。