Почему мой заказ не учитывает регистр из-за невозможности правильно отсортировать результаты? - PullRequest
0 голосов
/ 30 ноября 2018

Я использую MySql 5.6.15 на Amazon Linux.Я пытаюсь написать простой запрос, чтобы получить результаты, упорядоченные по строчной версии столбца 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 |

Ответы [ 3 ]

0 голосов
/ 05 декабря 2018

Отправленный вами SQL верен.Я создал SQL-скрипту , чтобы попытаться воспроизвести вашу проблему, используя данные в вашем вопросе, но она работает нормально. Закомментируйте предложение order by , и вы получите плохой результат, который вы показываете в своем вопросе.

Иногда строки UTF8 выглядят одинаково, но это не так.Вы убедились, что

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

возвращает 2 ожидаемые строки?

Если NAME идентичны, то нет такой сортировки, которая бы не помещала их рядом друг с другом.Единственная сортировка на NAME, которая соответствует результатам, которые вы видите, это та, где все 3 строки имеют идентичные значения NAME.Вы можете столкнуться с такого рода вещами в некотором контексте, где все строки преобразуются в целочисленные значения, а все имена преобразуются в ноль, но даже тогда я ожидаю, что порядок результатов останется согласованным между двумя запросами в вашем вопросе.

Существует ряд неясных способов усечения запроса, и я предполагаю, что наиболее вероятным объяснением того, что вы видите, является то, что предложение order by в первом запросе не делает его на сервере,Как вы выдаете запрос?Вы пытались использовать (другой) интерактивный способ выполнения запроса?Что если вы сохраните столбец MDR_NUMBER, но в своем запросе пропустите столбец IMPORT_ADMIN_DATA_FROM_SIS?

Можете ли вы воспроизвести проблему с помощью sqlfiddle.com?Если это так, пожалуйста, добавьте ссылку на ваш вопрос.

0 голосов
/ 09 декабря 2018

Выбор столбца не должен быть проблемой здесь.Я не уверен, как «школы округа Брэдли» оказываются между ними.Однако, если проблема заключается в чувствительности к регистру, вы можете использовать оператор BINARY.Это заставляет сравнение строк быть побайтовым, а не посимвольным.Найти более подробную информацию здесь

0 голосов
/ 04 декабря 2018

На самом деле вам не нужно использовать более низкое значение по порядку, это по умолчанию для MySQL.Кроме того, я никогда не видел такой ошибки ... Может быть, удалить нижнюю функцию из порядка и посмотреть, исправляет ли она это ...

Из документов MySQL: по столбцам символьного типа, сортировка -как и все другие операции сравнения, обычно выполняется без учета регистра.Это означает, что порядок не определен для столбцов, которые идентичны, за исключением их случая.Вы можете принудительно выполнить сортировку с учетом регистра для столбца, используя BINARY, например так: ORDER BY BINARY col_name.

...