За последние 24 часа нас посетил 18271 программист и 1637 роботов. Сейчас ищут 1655 программистов ...

DATE_FORMAT и ORDER BY

Тема в разделе "PHP и базы данных", создана пользователем Pavel_88, 6 июл 2013.

  1. Pavel_88

    Pavel_88 Новичок

    С нами с:
    6 июл 2013
    Сообщения:
    5
    Симпатии:
    0
    Всем привет, нужно мне было вывести комментарии с сортировкой и в один прекрасный день я заметил, что както не так сортируется. Тест выявил косяк и вот начал разбираться. Причина вот в чём:

    Код (Text):
    1. // Этот запрос отработает не коректно и выведет 2, 1, 3.
    2. $r = mysql_query("SELECT DATE_FORMAT(`date`, '%d.%m.%Y %H:%i:%s') AS `date`, `text` FROM `comments` ORDER BY `date` ASC") or die(mysql_error());
    3. // А вот тут будет всё правильно и выведет 3, 2, 1.
    4. $r = mysql_query("SELECT `date`, `text` FROM `comments` ORDER BY `date` ASC") or die(mysql_error());
    В чём причина?

    Для изучения накидал пример...

    Код (Text):
    1. <?php
    2. # Выставляем кодировку
    3. header("Content-type: text/html; charset=utf-8");
    4. #Выставляем максимальный уровень ошибок
    5. error_reporting(E_ALL);
    6. ?>
    7. <html><body>
    8. <a href="<?php echo 'http://'.$_SERVER['HTTP_HOST']?>">[ОГЛАВЛЕНИЕ]</a><br /><br />
    9. <?php
    10. # Тестовый скрипт
    11. echo "<b>Вывод из БД<br /><br />";
    12.  
    13. // Параметры подключения
    14. $user = "root"; $pass = ""; $db = "test";
    15. // Подключаемся к БД
    16. mysql_connect("localhost", $user, $pass) or die("Could not connect: ".mysql_error());
    17. // Создаём БД
    18. @mysql_query("CREATE DATABASE {$db}");
    19. // Выбираем БД
    20. mysql_select_db($db) or die("Could not select database: ".mysql_error());
    21.  
    22. // Создадим таблицу
    23. mysql_query("CREATE TABLE IF NOT EXISTS `comments` (
    24.             `id` int(5) NOT NULL AUTO_INCREMENT,
    25.             `cover_id` int(5) NOT NULL DEFAULT '0',
    26.             `parent_id` int(5) NOT NULL DEFAULT '0',
    27.             `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
    28.             `user_id` int(5) NOT NULL DEFAULT '0',
    29.             `author` varchar(50) NOT NULL DEFAULT '',
    30.             `text` text NOT NULL,
    31.             PRIMARY KEY (`id`),
    32.             KEY `cover_id` (`cover_id`),
    33.             KEY `parent_id` (`parent_id`)
    34.             ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=54;"
    35.             ) or die(mysql_error());
    36.  
    37. // Дамп
    38. /*
    39. mysql_query("INSERT INTO `comments` (`id`, `cover_id`, `parent_id`, `date`, `user_id`, `author`, `text`) VALUES
    40.             (52, 29, 0, '2013-07-01 19:08:53', 7, 'admin', '2'),
    41.             (51, 29, 0, '2013-06-30 20:20:04', 7, 'admin', '3'),
    42.             (53, 29, 0, '2013-07-01 22:35:24', 7, 'admin', '1');"
    43.             ) or die(mysql_error());
    44. */
    45.  
    46. // Этот запрос отработает не коректно и выведет 3, 1, 2.
    47. $r = mysql_query("SELECT DATE_FORMAT(`date`, '%d.%m.%Y %H:%i:%s') AS `date`, `text` FROM `comments` ORDER BY `date` DESC") or die(mysql_error());
    48. // А вот тут будет всё правильно и выведет 3, 2, 1.
    49. //$r = mysql_query("SELECT `date`, `text` FROM `comments` ORDER BY `date` ASC") or die(mysql_error());
    50. for ($data = array(); $row = mysql_fetch_assoc($r); $data[] = $row);
    51. echo "<pre>"; print_r($data); echo "</pre>";
    52. # Конец программы
    53. ?>
    54. </body></html>
     
  2. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Задайте другое название для псевдонима поля date и все будет работать нормально:
    Код (PHP):
    1. $r = mysql_query("SELECT DATE_FORMAT(`date`, '%d.%m.%Y %H:%i:%s') AS `format_date`, `text` 
    2.     FROM `comments` 
    3. ORDER BY `date` DESC") or die(mysql_error());
    4.  
     
  3. Pavel_88

    Pavel_88 Новичок

    С нами с:
    6 июл 2013
    Сообщения:
    5
    Симпатии:
    0
    Спасибо, теперь сортирует как надо )
     
  4. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    Зачем нагружать базу еще всякими вычислениями...
    На мой взгляд правильней задать формат дате через PHP.
     
  5. Pavel_88

    Pavel_88 Новичок

    С нами с:
    6 июл 2013
    Сообщения:
    5
    Симпатии:
    0
    А есть значимая разница в скорости? Честно говоря погуглил и ничего не нашёл. Но мне кажется, что мускул отработает быстрее.
     
  6. smitt

    smitt Старожил

    С нами с:
    3 янв 2012
    Сообщения:
    3.166
    Симпатии:
    65
    В данном случае база предпочтительней... все ок.
     
  7. deblogger

    deblogger Новичок

    С нами с:
    11 июл 2013
    Сообщения:
    200
    Симпатии:
    0
    Тогда скрипт должен будет знать о поле "date". Если вы прописали в скрипте нечто =$res["date"]; то скрипт стал частью БД и mySQL. То есть задача так или иначе решается однозначно.

    Добавлено спустя 18 минут 51 секунду:
    При чем тут скорость. Отношения выносятся выше переменных - в логику интерфейса.

    Получив рекордсет вы должны его раскидать по хтмлю. Если вы делаете как выше описано - повторяете буквально сведения из БД в скрипте - то получится как выше описано. Если все берется из резалта - все сведения в нем должны быть готовы к применению.

    Типичный пример - вывести данные работника (товара, услуги и тп) на страницу. Выводим в цикле создавая одноименные элементы по каждому полю беря сведения для оформления элементов из свойства поля. В mysql есть fetch_field или типа того, но возвращается не все. В частности каммент взять нельзя. Следовательно сперва придется потребовать от information_schema все что нужно по каждому полю и пользуясь тривиальной логикой сопоставить сведения о полях тем или иным тэгам хтмл.

    Собственно так и сделан phpmyadmin.

    У меня есть ощущение что такие страницы как phpmyadmin народ воспринимает как какой-нибудь экзешник, типа приложение. Приложение, конечно, но веб. Следовательно надо просто посмотреть как оно устроено изнутри и сделать так же, в смысле логики,