Ответы пользователя по тегу MySQL
  • Как отключить обновление поля date(TIMESTAMP) при UPDATE другого поля этой строки?

    @Sayonji
    Просто добавьте это поле в список обновляемых:
    UPDATE table SET status = 'false', date = date WHERE date < NOW() - INTERVAL 1 HOUR;
    Ответ написан
  • Как не допустить повторение данных в MySQL при ORDER by rand() LIMIT $limit,10?

    @Sayonji
    На SQL:
    Я думаю, что для ваших целей сгодится псевдослучайная перестановка.
    Шаг 1: Сохраните длину таблицы, пусть $N.
    Шаг 2: Выбирите большое (больше $N) число $P, взаимопростое с $N. Это можно сделать с помощью алгоритма для генерации простых чисел.
    Шаг 3: Пусть (Q) это запрос, который возвращает нужные вам данные из таблицы, а также поле rownum, являющееся номером строки соответствующей записи. Тогда теперь вы можете сделать так:
    SELECT * FROM (Q) ORDER BY $P * rownum % $N LIMIT $limit, 10;

    Не на SQL:
    Шаг 1: Сгенерируйте случайную перестановку заранее, пусть она будет в массиве $perm, сохраните ее в сессию или еще куда-то.
    Шаг 2: Выберите нужные индексы:
    $indices = array_slice($perm, $limit, 10);
    $indices = join(", ", $indices);
    Шаг 3: Запрос: SELECT * FROM (Q) WHERE rownum IN ($indices)

    Если хочется без подзапроса, дающего номера строк, то придется запоминать первичные ключи уже возвращенных записей и добавлять в конец запроса WHERE id_key NOT IN (...).

    UPD Еще подход, попроще.

    Запрос такой:
    "SELECT * FROM table ORDER BY func(id_key) LIMIT $limit, 10;"
    Здесь func это некоторая функция, преобразующая первичный ключ случайным обзром (он ведь числовой?). Например, подойдет $P * id_key % $T, где $P это большое случайное нечетное число, сгенерированное заранее, а $T это степень двойки большая последнего id_key.
    Например, подойдет
    $T = 2^31;
    $P = (rand(2^26, 2^30) - 1) * 2 - 1;
    Запрос будет такой:
    "SELECT * FROM thetable ORDER BY CAST(id_key AS BIGINT) * $P % $T LIMIT $limit, 10;"

    Это даст около миллиарда различных вариантов перемешивания.

    В случае, если в таблицу будет добавлена новая запись, или удалена старая, все эти варианты (кроме запоминания уже вышедших айдишников) могут дать сбой, а именно попадание одной старой записи в выборку еще раз.
    Ответ написан
    3 комментария
  • Почему происходит ошибка mysqli_fetch_array()?

    @Sayonji
    Не срабатывает запрос, причина может быть любая, например, "WHERE `views`" выглядит странным условием.
    Ответ написан
  • Как сделать выборку с округлением до 50?

    @Sayonji
    В математике округление с произвольным шагом делается стандартной операцией:
    50 * round(X / 50)
    Ответ написан
    1 комментарий
  • Как правильно посчитать среднее количество?

    @Sayonji
    Вы хотите посчитать среднее от пяти чисел. Это значит сложить их и разделить на 5, то есть
    SELECT COUNT(*) / 5 FROM `users`
    JOIN `records` ON `records`.`user_id` = `users`.`id`
    WHERE `records`.`created_at` > NOW() - INTERVAL 5 DAY
    Ответ написан
    Комментировать
  • Как правильно организовать структуру таблицы MySQL?

    @Sayonji
    1. Стоит объединить таблицы. Иначе, по-первых, возникнут проблемы с foreign key. Например, вы заходите сделать таблицу operations_history с ключом на пользователя, но не сможете, поскольку пользователи разбиты. Во-вторых, все равно потом появятся запросы по всем пользователям. Например, вам точно рано или поздно захочется найти юзера по имени, и делать это по трём таблицам будет запарно. В-третьих, потом еще появятся менеджеры, контрагенты... Будете плодить таблицы?
    2. Тут вопрос только в производительности. Вынос поля в отдельную таблицу ускорит выборку, когда это поле не используется, и замедлит, когда используется. Я обычно делаю одну дополнительную таблицу, т. е. не phone_numbers, а user_meta_info, куда пишу номера телефона, года рождения и другую инфу, которая нужна только для отображения, но не фигурирует в логике системы. А имя, группу и другие данные, которые нужны почти всегда когда используется сущность user, кладу в основную таблицу.
    Ответ написан
    2 комментария
  • Почему не работает STR_TO_DATE в подзапросе?

    @Sayonji
    Возможно, при использовании вашего интерфейса ко второму запросу неявно добавляется что-то вроде LIMIT 0,100 (чтобы не выводилось на экран всё), и обработка таблицы orders не доходит до записией с пустым полем data, приводящих к ошибке в случае CREATE TABLE.
    Ответ написан
    1 комментарий
  • Генерация JSON с вложенными объектами

    @Sayonji
    Разве что так:
        $q = db_query('SELECT CONCAT(
            "{\"postid\" : \"",
            posts.postid
            "\", \"user\" : {\"username\" : \"",
            users.username,
            "\", \"userid\" : \"",
            users.userid,
            "\"}}"
        ) as res
        FROM posts LEFT JOIN users ON posts.userid = users.userid');
        var_dump(mysql_fetch_all($q));
    

    array(2) {
      [0]=>
      array(1) {
        ["res"]=>
        string(85) "{"postid" : "15", "user" : {"username" : "noobishe", "userid" : "7"}}"
      }
      [1]=>
      array(1) {
        ["res"]=>
        string(79) "{"postid" : "19", "user" : {"username" : "pro!", "userid" : "8"}}"
      }
    
    Ответ написан
    Комментировать
  • Задание пользовательских прав с помощью динамического запроса?

    @Sayonji
    Нельзя подготавливать сложные запросы.
    PREPARE stmt_name FROM preparable_stmt
    preparable_stmt is either a string literal or a user variable that contains the text of the SQL statement. The text must represent a single statement, not multiple statements.
    Ответ написан
    4 комментария
  • C архитектурой/выборкой с таблицы?

    @Sayonji
    Передавайте назад только айди записей, которые имеют дату ту же, что дата_последнего_сообщения, раз вас смущают большие запросы.
    А потом как выше предлагали WHERE date_created <= $last AND id not in $ids. Получать эти айди на клиенте можно, если жалко серверного времени.
    Ответ написан