简体   繁体   English

MySQL查询在更新后以不同的顺序返回列

[英]MySQL query returns columns in different order after update

One of my programs was using this query to get the details of a selected table's columns:我的一个程序正在使用此查询来获取所选表的列的详细信息:

SELECT c.COLUMN_NAME as column_name,
       c.COLUMN_TYPE as column_type,
       c.CHARACTER_MAXIMUM_LENGTH as length,
       c.TABLE_NAME as table_name,
       c.COLUMN_COMMENT as column_comment,
       k.REFERENCED_TABLE_NAME as reference_table,
       k.REFERENCED_COLUMN_NAME as reference_column
FROM information_schema.COLUMNS as c
LEFT JOIN information_schema.KEY_COLUMN_USAGE as k
    ON (k.TABLE_SCHEMA=c.TABLE_SCHEMA
   AND k.TABLE_NAME=c.TABLE_NAME
   AND k.COLUMN_NAME=c.COLUMN_NAME
   AND k.POSITION_IN_UNIQUE_CONSTRAINT IS NOT NULL)
 WHERE c.TABLE_SCHEMA='$db_name'
   AND c.TABLE_NAME='$table_name'

The result used to be:结果曾经是:

array(36) { [0]=> array(7) { ["column_name"]=> string(2) "id" ["column_type"]=> string(7) ... array(36) { [0]=> array(7) { ["column_name"]=> string(2) "id" ["column_type"]=> string(7) ...

The first column in that table is id , and in the results array, the first index was id (as it's supposed to be).该表中的第一列是id ,在结果数组中,第一个索引是id (它应该是)。

Now, however, after updating PHP (from 5.6 to 7.3) and MySQL, the results are sorting differently.但是,现在更新 PHP(从 5.6 到 7.3)和 MySQL 后,结果排序有所不同。

It is not sorting based on column's creation date priority and is instead sorting based on some unknown element ( id is 3rd index in array).不是基于列的创建日期优先级排序,而是基于某些未知元素( id是数组中的第三个索引)进行排序。

Is this a bug or something?这是错误还是什么? How can I get the original sorting order back?我怎样才能恢复原来的排序顺序?


Okay, I just figured something out.好吧,我刚刚想到了一些东西。 MySQL is sorting the columns with a foreign keys first, and then the rest of the columns. MySQL首先使用外键对列进行排序,然后对其余的列进行排序。

I don't want this!我不要这个! How can I get the original sort order back?我怎样才能恢复原来的排序顺序?


Here are my results.这是我的结果。 First is the current (wrong) output, then the expected output.首先是当前(错误)输出,然后是预期输出。

Incorrect output错误的输出

column_name column_type length  table_name  column_comment  reference_table reference_column


qdqe_group  varchar(15)     15  md_report   name/Mach_Name  mach            Op_ID
owner       varchar(25)     25  md_report                   users           uName
Pile        varchar(12)     12  md_report                   depo            Depo_ID
Co_ID       varchar(3)       3  md_report   name/Co_NameF   contractors     Co_ID
Region_ID   varchar(2)       2  md_report   dependent/Mine_ID   regions     Region_ID
id          int(11)       NULL  md_report                   NULL            NULL
Submit_Date timestamp     NULL  md_report                   NULL            NULL
asd_ID      varchar(2)       2  md_report   input/multiple- NULL            Null
                                            asd-asd_ID,asd_
                                            nameF
wer_Report  date          NULL  md_report                   NULL            NULL
sdf_Qty     int(2)        NULL  md_report                   NULL            NULL
jyu_Time    time          NULL  md_report                   NULL            NULL
yuj_Work    float(6,2)    NULL  md_report                   NULL            NULL
Al2O3       float(4,2)    NULL  md_report                   NULL            NULL
SiO2        float(4,2)    NULL  md_report                   NULL            NULL
nh_Time     time          NULL  md_report                   NULL            NULL
ju_Work     float(6,2)    NULL  md_report                   NULL            NULL
we_Time     time          NULL  md_report                   NULL            NULL
xcv_Work    float(6,2)    NULL  md_report                   NULL            NULL
trh_Time    time          NULL  md_report                   NULL            NULL
ewr_Work    float(6,2)    NULL  md_report                   NULL            NULL
fgh_Time    time          NULL  md_report                   NULL            NULL
ert_Work    float(6,2)    NULL  md_report                   NULL            NULL
dfg_Time    time          NULL  md_report                   NULL            NULL
vf_Work     float(9,2)    NULL  md_report                   NULL            NULL
as_Time     time          NULL  md_report                   NULL            NULL

Here it is their real position in MySQL: (I changed some of the names for personal reasons)这是他们在 MySQL 中的真实位置:(我因个人原因更改了一些名称)

Expected output预期输出

column_name column_type length  table_name  column_comment  reference_table reference_column


id          int(11)       NULL  md_report                   NULL            NULL
Submit_Date timestamp     NULL  md_report                   NULL            NULL
owner       varchar(25)     25  md_report                   users           uName
wer_Report  date          NULL  md_report                   NULL            NULL
Co_ID       varchar(3)       3  md_report   name/Co_NameF   contractors     Co_ID
Region_ID   varchar(2)       2  md_report   dependent/Mine_ID   regions     Region_ID
asd_ID      varchar(2)       2  md_report   input/multiple- NULL            NULL
                                            asd-asd_ID,asd_
                                            nameF
qdqe_group  varchar(15)     15  md_report   name/Mach_Name  mach            Op_ID
sdf_Qty     int(2)        NULL  md_report                   NULL            NULL
jyu_Time    time          NULL  md_report                   NULL            NULL
yuj_Work    float(6,2)    NULL  md_report                   NULL            NULL
Pile        varchar(12)     12  md_report                   depo            Depo_ID
Al2O3       float(4,2)    NULL  md_report                   NULL            NULL
SiO2        float(4,2)    NULL  md_report                   NULL            NULL
nh_Time     time          NULL  md_report                   NULL            NULL
ju_Work     float(6,2)    NULL  md_report                   NULL            NULL
we_Time     time          NULL  md_report                   NULL            NULL
xcv_Work    float(6,2)    NULL  md_report                   NULL            NULL
trh_Time    time          NULL  md_report                   NULL            NULL
ewr_Work    float(6,2)    NULL  md_report                   NULL            NULL
fgh_Time    time          NULL  md_report                   NULL            NULL
ert_Work    float(6,2)    NULL  md_report                   NULL            NULL
dfg_Time    time          NULL  md_report                   NULL            NULL
vf_Work     float(9,2)    NULL  md_report                   NULL            NULL
as_Time     time          NULL  md_report                   NULL            NULL

As you can see, MySQL sorted all the columns with references at the top of the results.如您所见,MySQL 将所有带有引用的列排序在结果的顶部。

I want to get them in their real position with those details.我想通过这些细节让他们处于真正的位置。

The new result is not logical anyway.无论如何,新的结果是不合逻辑的。 I would really appreciate it if you could explain to me what is happening here.如果您能向我解释这里发生的事情,我将不胜感激。

There is no "default" sort order in a SQL table, at least none which is required by the ANSI standard (or, as you have seen here, implemented by MySQL). SQL 表中没有“默认”排序顺序,至少没有 ANSI 标准(或者,正如您在此处看到的,由 MySQL 实现)所要求的。 If you want your result set in a certain order, you should add a proper ORDER BY clause, eg如果您希望结果集按特定顺序排列,则应添加适当的ORDER BY子句,例如

SELECT
    c.COLUMN_NAME as column_name,
    c.COLUMN_TYPE as column_type,
    ...
ORDER BY
    c.COLUMN_NAME;

As to why the perceived sort order has changed, it probably has to do with how the records are being fetched from the database.至于为什么感知的排序顺序发生了变化,它可能与如何从数据库中获取记录有关。 As the underlying data changes, the way MySQL will choose to access the records might also change.随着底层数据的变化,MySQL 选择访问记录的方式也可能会发生变化。

I don't know why your output changed, but I think that to get the output you want, you can use an ORDER BY clause to order by the ordinal position.我不知道为什么你的输出改变了,但我认为要获得你想要的输出,你可以使用ORDER BY子句按序数位置排序。

ORDER BY c.ORDINAL_POSITION

When I ran your query on one of my own MySQL databases, I added a c.* to your list of SELECT ed columns.当我在我自己的一个 MySQL 数据库上运行您的查询时,我在您的SELECT ed 列列表中添加了一个c.* From all the extra columns displayed, the ORDINAL_POSITION seems like it might be what you are looking for.从显示的所有额外列中, ORDINAL_POSITION似乎可能是您正在寻找的。

So your final query might looks something like this:因此,您的最终查询可能如下所示:

SELECT c.COLUMN_NAME as column_name,
       c.COLUMN_TYPE as column_type,
       c.CHARACTER_MAXIMUM_LENGTH as length,
       c.TABLE_NAME as table_name,
       c.COLUMN_COMMENT as column_comment,
       k.REFERENCED_TABLE_NAME as reference_table,
       k.REFERENCED_COLUMN_NAME as reference_column
FROM information_schema.COLUMNS as c
LEFT JOIN information_schema.KEY_COLUMN_USAGE as k
    ON (k.TABLE_SCHEMA=c.TABLE_SCHEMA
      AND k.TABLE_NAME=c.TABLE_NAME
      AND k.COLUMN_NAME=c.COLUMN_NAME
      AND k.POSITION_IN_UNIQUE_CONSTRAINT IS NOT NULL)
WHERE c.TABLE_SCHEMA='$db_name'
      AND c.TABLE_NAME='$table_name'
ORDER BY c.ORDINAL_POSITION

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM