为什么我的顺序不区分大小写,却无法正确排序结果?

lmvvr0a8  于 2021-06-17  发布在  Mysql
关注(0)|答案(3)|浏览(291)

我在amazonlinux上使用mysql 5.6.15。我正在尝试编写一个简单的查询,以获得按表的name列的小写版本排序的结果,该列的类型为varchar(100)。表具有属性

ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

但请注意,我得到了不同的结果,唯一不同的是,在下面的错误结果中,我得到了一个额外的列。。。

mysql> select NAME, ACTIVE, ADDRESS_ID, COUNTRY_ID, CREATED_ON, ORGANIZATION_ID, IMPORT_ADMIN_DATA_FROM_SIS, IMPORT_DATA_FROM_SIS, MDR_NUMBER from organization order by lower(NAME);
+--------------------------------------+--------+------------+------------+---------------------+-----------------+----------------------------+----------------------+------------+
| NAME                                 | ACTIVE | ADDRESS_ID | COUNTRY_ID | CREATED_ON          | ORGANIZATION_ID | IMPORT_ADMIN_DATA_FROM_SIS | IMPORT_DATA_FROM_SIS | MDR_NUMBER |
+--------------------------------------+--------+------------+------------+---------------------+-----------------+----------------------------+----------------------+------------+
| Billy Madison Elementary             |       | NULL       | US         | 2018-11-29 22:35:57 | 7788            |                            |                    0 | NULL       |
| Bradley County Schools               |       | NULL       | US         | 2018-11-29 22:35:57 | 8888            |                            |                    0 | NULL       |
| Billy Madison Elementary             |       | NULL       | US         | 2018-11-29 22:35:57 | 9998            |                            |                    0 | NULL       |

当我不要求额外的列,我得到正确的结果。。。

mysql> select NAME, ACTIVE, ADDRESS_ID, COUNTRY_ID, CREATED_ON, ORGANIZATION_ID, IMPORT_ADMIN_DATA_FROM_SIS, IMPORT_DATA_FROM_SIS from organization order by lower(NAME);
+--------------------------------------+--------+------------+------------+---------------------+-----------------+----------------------------+----------------------+
| NAME                                 | ACTIVE | ADDRESS_ID | COUNTRY_ID | CREATED_ON          | ORGANIZATION_ID | IMPORT_ADMIN_DATA_FROM_SIS | IMPORT_DATA_FROM_SIS |
+--------------------------------------+--------+------------+------------+---------------------+-----------------+----------------------------+----------------------+
| Billy Madison Elementary             |       | NULL       | US         | 2018-11-29 22:35:57 | 9998            |                            |                    0 |
| Billy Madison Elementary             |       | NULL       | US         | 2018-11-29 22:35:57 | 7788            |                            |                    0 |
| Bradley County Schools               |       | NULL       | US         | 2018-11-29 22:35:57 | 8888            |                            |                    0 |

这到底是怎么回事?如何返回按小写名称排序的结果?

**编辑:**运行“show create table”创建表语句。。。

| organization | CREATE TABLE `organization` (
  `ID` varchar(32) COLLATE utf8_bin NOT NULL,
  `STATE_ID` varchar(10) COLLATE utf8_bin DEFAULT NULL,
  `ORGANIZATION_ID` varchar(32) COLLATE utf8_bin NOT NULL,
  `COUNTRY_ID` varchar(10) COLLATE utf8_bin NOT NULL,
  `NAME` varchar(100) COLLATE utf8_bin NOT NULL,
  `ORGANIZATION_TYPE_ID` varchar(2) COLLATE utf8_bin NOT NULL,
  `PARENT_ORGANIZATION_ID` varchar(32) COLLATE utf8_bin DEFAULT NULL,
  `USER_ENTERED` tinyint(4) DEFAULT '0',
  `SAMPLE_ORGANIZATION` tinyint(4) DEFAULT '0',
  `IMPORT_DATA_FROM_SIS` tinyint(1) NOT NULL DEFAULT '0',
  `USE_EXTERNAL_AUTHENTICATION` tinyint(1) NOT NULL DEFAULT '0',
  `ADDRESS_ID` varchar(32) COLLATE utf8_bin DEFAULT NULL,
  `LTI_REFERER_DOMAIN` varchar(32) COLLATE utf8_bin DEFAULT NULL,
  `URL_ID` varchar(32) COLLATE utf8_bin DEFAULT NULL,
  `CREATED_ON` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `MDR_NUMBER` varchar(32) COLLATE utf8_bin DEFAULT NULL,
  `ACTIVE` bit(1) DEFAULT b'1',
  `IMPORT_ADMIN_DATA_FROM_SIS` bit(1) DEFAULT b'0',
  `USE_EXTERNAL_AUTH_FOR_ADMINS` bit(1) DEFAULT b'0',
  PRIMARY KEY (`ID`),
  UNIQUE KEY `UK_ORGANIZATION` (`ORGANIZATION_ID`),
  KEY `FK1_ORGANIZATION` (`COUNTRY_ID`),
  KEY `FK3_ORGANIZATION` (`ORGANIZATION_TYPE_ID`),
  KEY `FK2_ORGANIZATION` (`PARENT_ORGANIZATION_ID`),
  KEY `FK_ORGANIZATION` (`ADDRESS_ID`),
  KEY `FK5_ORGANIZATION` (`URL_ID`),
  CONSTRAINT `FK1_ORGANIZATION` FOREIGN KEY (`COUNTRY_ID`) REFERENCES `cb_country` (`ID`) ON DELETE CASCADE ON UPDATE NO ACTION,
  CONSTRAINT `FK2_ORGANIZATION` FOREIGN KEY (`PARENT_ORGANIZATION_ID`) REFERENCES `organization` (`ID`) ON DELETE CASCADE ON UPDATE NO ACTION,
  CONSTRAINT `FK3_ORGANIZATION` FOREIGN KEY (`ORGANIZATION_TYPE_ID`) REFERENCES `cb_org_type` (`ID`) ON DELETE CASCADE ON UPDATE NO ACTION,
  CONSTRAINT `FK5_ORGANIZATION` FOREIGN KEY (`URL_ID`) REFERENCES `sb_url` (`ID`) ON UPDATE NO ACTION,
  CONSTRAINT `FK_ORGANIZATION` FOREIGN KEY (`ADDRESS_ID`) REFERENCES `cb_address` (`ID`) ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin |
3hvapo4f

3hvapo4f1#

列选择不应该是这里的问题。我不知道“布拉德利郡学校”是如何介于两者之间的。但是,如果大小写敏感的问题,那么您可以使用二进制运算符。它强制字符串逐字节比较,而不是逐字符比较。请在此处查找更多详细信息

ih99xse1

ih99xse12#

您实际上不需要在order by语句中使用lower,这是mysql的默认值。除此之外,我从没见过这样的虫子。。。也许可以从order中删除lower函数,看看它是否修复了它。。。
在mysql docs中:对于字符类型的列,排序与所有其他比较操作一样,通常以不区分大小写的方式执行。这意味着除了大小写之外,对于相同的列,顺序是未定义的。您可以使用binary对列强制进行区分大小写的排序,例如:orderbybinary col\u name。

avkwfej4

avkwfej43#

您发布的sql是正确的。我创建了一个sql fiddle,试图使用问题中的数据重现问题,但效果很好。注解掉 order by 子句,你就会得到你在问题中表现出来的坏结果。
有时utf8字符串看起来相同,但实际上不同。你证实了吗

select * from organization where name = "Billy Madison Elementary"

返回所需的2行?
如果 NAME s是相同的,没有一种排序方法不把它们放在一起。唯一的选择 NAME 这与您看到的结果一致,即所有3行都具有相同的 NAME 价值观。在某些上下文中,您可能会遇到这种情况,其中字符串都转换为整数值,所有名称都转换为零,但即使这样,我还是希望您的问题中的两个查询之间的结果顺序保持一致。
有许多模糊的方法可以截断查询,我猜最有可能的解释是 order by 第一个查询中的子句没有发送到服务器。您是如何发出查询的?您是否尝试过使用(不同的)交互方式来运行查询?如果你留着钥匙呢 MDR_NUMBER 列,但省略 IMPORT_ADMIN_DATA_FROM_SIS 查询中的列?
你能用sqlfiddle.com重现这个问题吗?如果是这样,请在问题中添加链接。

相关问题