В колонке таблицы MySQL (тип text) находятся записи типа: /частьurl/15/ /частьurl/1235/ /частьurl/743/ и т.п. где "частьurl" везде одинакова. возможно ли отсортировать запрос по числу, чтобы порядок был 15, 743, 1235 (а не как у строки 1235, 15, 743)?
вы можете отсортировать по любому выражению, в т.ч. с преобразоыванием типов. вроде ORDER BY CAST((SUBSTRING(f, 11, 5) AS UNSIGNED) должно работать, хотя и медленно. см. здесь а чтобы оно при этом использовало индекс - наверное только через вычисляемые поля (generated column), но это неточно. ищите и проверяй сами.
Не лучшим решением будет выполнить usort с php, просто если данных реально много, запрос будет достаточно тяжелым. PHP: (int) filter_var(ТВОЙ УРЛ ИЗ ТАБЛИЦЫ, FILTER_SANITIZE_NUMBER_INT);
если таблица совсем маленькая и мы точно должны получить её всю на php, тогда можно и так. но как только нам понадобится получить часть, LIMIT n, m так сразу отпадает.
Добрый день! Возно не самое оптимальное решение, но провено, работает Код (Text): SELECT A FROM `myTable` ORDER BY SOUNDEX(A), LENGTH(A), A; Результат: /частьurl/15/ /частьurl/743/ /частьurl/1235/ Удачи!
Вам изначально нужно в таблицу дополнить дополнительное поле url_id и туда добавлять номера, которые в php отделяются перед INSERT в БД. Измените таблицу и дополните, вам же лучше потом будет.
Это была первая мысль. Но дело в том, что таблица содержит все url сайта, в части из которых url_id нет, а в другой части они в другой части url. Так что такое решение представляется невозможным. --- Добавлено --- Спасибо. Неожиданно.
Задача поставлена точно: возможно ли отсортировать запрос по числу... и т.д. По дополнительному полю (int) я сортировать умею
PHP: <?php declare(strict_types = 1); error_reporting(-1); $host = 'localhost'; $db = 'test'; $user = 'root'; $pass = ''; $charset = 'utf8mb4'; $dsn = "mysql:host=$host;dbname=$db;charset=$charset"; $options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]; try { $pdo = new PDO($dsn, $user, $pass, $options); } catch (\PDOException $e) { throw new \PDOException($e->getMessage(), (int)$e->getCode()); } /* $stmt = $pdo->prepare('INSERT INTO `url` (`text`) VALUES (:text)'); $pdo->beginTransaction(); //- Добавляем 1 млн записей в таблицу try { for ($i = 0; $i < 1000000; $i++) { $uniqueText = '/частьurl/' . random_int(100000000000000, 999999999999999); $stmt->execute(['text' => $uniqueText]); } $pdo->commit(); } catch (Exception $e) { $pdo->rollBack(); throw $e; } */ $query = "SELECT * FROM `url` ORDER BY `id` ASC LIMIT 300"; $result = $pdo->query($query); $rows = $result->fetchAll(PDO::FETCH_ASSOC); usort($rows, function ($a, $b) { $numberA = (int) filter_var($a['text'], FILTER_SANITIZE_NUMBER_INT); $numberB = (int) filter_var($b['text'], FILTER_SANITIZE_NUMBER_INT); return $numberB - $numberA; // Для сортировки по убыванию }); foreach ($rows as $row) { echo $row['text'] . " <br />"; } 1) Закомментировал принцип добавления 1 млн записей. 2) Обычный запрос ( добавить пагинацию сможешь сам ) 3) Стандартный запрос к бд на получении с учетом сортировки, далее фильтр по text-id 4) Если тебе прям нужно сортировать изначально по id, что находиться в text, я в общем-то не советую тратить ресурсы сервера, время на решение проблем, а сделать иначе. Всегда можно получить получить все записи и например изменить их/перезаписать. Это будет проще во всех смыслах слова. Люди сверху правильно изначально посоветовали. Решать уже тебе ) p.s. возможно, что я понял вообще неправильно..) --- Добавлено --- Код (Text): SELECT *, CAST(REGEXP_SUBSTR(text, '\\d+') AS UNSIGNED) AS a_url FROM url ORDER BY a_url ASC LIMIT 100; Если нужно сразу сортировать, то примерно такой вариант, но имхо, это бредовый вариант, запрос порядка 1+- сек выполняется при 1 млн записей.
Возможно, если добавить еще одну колонку url_category_id, и будем знать какие значения url к одной категории относится а какие другие