Запрос работает на локальном хосте, но не на рабочем сервере

Мой английский не так хорош, но я попытаюсь объяснить проблему.

У меня есть три таблицы: одна называется Accounts, одна называется Accounts_Profiles, а другая называется Accounts_Messages. Моя цель — показать последних пользователей, которым вошедший в систему пользователь ($login_user_id) отправил сообщение.
Мои таблицы в основном состоят из этого:

Accounts

идентификатор, имя, электронная почта, нивел, проверка

Accounts_Profiles

идентификатор, user_id, статус

Accounts_Messagens

идентификатор, отправитель (int), получатель (int)

Мой запрос в настоящее время выглядит так: SELECT DISTINCT Accounts.id, Accounts.email, Accounts.name, Accounts.username, Accounts.avatar, Accounts.nivel, Accounts.verification FROM Accounts JOIN Accounts_Messages ON Accounts.id = Accounts_Messages.receiver ORDER BY Accounts_Messages.id DESC;

В CodeIgniter/PHP это выглядит так:

/*
    With the $this->db->distinct() I make sure that the users shown will not be repeated - It works!
*/
$this->db->distinct();
$this->db->select(
    array(
        "Accounts.id id",
        "Accounts.email email",
        "Accounts.name name",
        "Accounts.username username",
        "Accounts.avatar avatar",
        "Accounts.nivel nivel",
        "Accounts.verification verification",
        "Accounts_Profiles.status online",
        "(SELECT IF(COUNT(ACM.id) > 0, COUNT(ACM.id), null) FROM Accounts_Messages ACM WHERE ACM.receiver = '$login_user_id' AND ACM.sender = 'Accounts.id' AND ACM.is_read = '0') unread"
    )
);

/*
    Here I exclude the $login_user_id from the list, the admin users and also those who have not verified the account - It works!
*/
$this->db->join(
    "Accounts_Profiles",
    "Accounts_Profiles.user_id = Accounts.id", 
    "left"
);
$this->db->where(
    array(
        "Accounts.id ! = " => $login_user_id,
        "Accounts.nivel ! = " => 'administrator',
        "Accounts.verification ! = " => 'false'
    )
);

/*
    Here, I sort messages by last sent. I check who the logged in user sent the last messages to and list those users - This only works on localhost.
*/
$this->db->join(
    "Accounts_Messages", 
    "Accounts.id = Accounts_Messages.receiver", 
    "left"
);
$this->db->order_by(
    "Accounts_Messages.id", 'DESC'
);

/*
    Returning the result
*/
return $this->db->limit($filters['limit'])->offset($filters['offset'])->get("Accounts")->result();

Проблема: Это работает на локальном хосте, но не работает в производстве. На локальном хосте я использую MySQL. На рабочем сервере я использую MariaDB. Теоретически это не должно иметь никакого значения, так как использованные мной предложения совместимы в обоих случаях.

Я забыл что-то сделать или настроить на рабочем сервере?

Спасибо!

Я пытался добавить это для совести, но это не сработало:
$this->db->group_by( "Accounts.id" );


Редактировать

Как видите, в localhost порядок пользователей определяется последним отправленным им сообщением. Это то, что я ожидаю в производстве.

На рабочем сервере упорядочивание происходит по дате создания разговора (я не знаю, как). Это неправильно, так как первые пользователи, с которыми я общаюсь, всегда приходят последними, даже если я отправляю им новое сообщение.

"это не работает в продакшене" - что это значит? Что произойдет, если вы запустите его? Есть ли ошибка? Кроме того, вы должны использовать ту же систему баз данных в своей системе разработки, чтобы избежать таких проблем.

Nico Haase 23.01.2023 20:49

Привет, @NicoHaase! Я проводил одни и те же тесты на одних и тех же машинах не менее 5 лет... Я впервые сталкиваюсь с этой проблемой. Он не отображает ошибки. Сортировка просто не идет как надо. Код абсолютно одинаков в обоих случаях (localhost и live server). Все всегда работало нормально. Я никогда не делал ничего, чтобы работать исключительно с MariaDB.

Jesse Gaspar 23.01.2023 20:55

Можете ли вы запустить запрос SELECT VERSION(); как на локальном, так и на рабочем сервере и сообщить, что говорит каждый из них?

Bill Karwin 23.01.2023 20:56

Привет, @BillKarwin! Конечно! MySQL: 8.0.31. MariaDB: 10.1.48-MariaDB-0+deb9u1

Jesse Gaspar 23.01.2023 21:00

Вы пытались выполнить запрос непосредственно к базе данных? И это может показаться глупым вопросом, но вы загружали данные в рабочую базу данных?

aynber 23.01.2023 21:05

Привет, @aynber! Спасибо за вопрос. Да, две базы данных абсолютно одинаковы. Между ними нет различий. Я попытался выполнить запрос через терминал, а также через PhpMyAdmin... он работает только на локальном хосте. :/

Jesse Gaspar 23.01.2023 21:10

И что происходит, когда вы запускаете его в производственной системе? Это дает пустой результат?

Nico Haase 23.01.2023 21:11

Его @NicoHaase! Не возвращает пустые результаты. Он возвращает список с другим порядком, чем тот, который я определил в запросе. Мой запрос должен вернуть последних пользователей, которым я отправил сообщение, в порядке убывания (и это то, что происходит на локальном хосте). Короче говоря, в производстве он сортируется по дате создания разговора, а не по идентификатору сообщения.

Jesse Gaspar 23.01.2023 21:26

Пожалуйста, добавьте все пояснения к вашему вопросу, отредактировав его. Если запрос не выполняется должным образом, когда вы используете что-то вроде phpMyAdmin, мне это не кажется связанным с CodeIgniter. Поделитесь структурой таблицы, образцами данных, запросом и ожидаемым результатом

Nico Haase 23.01.2023 21:29

Спасибо, @NicoHaase! Я уже отредактировал вопрос с тем, что вы упомянули.

Jesse Gaspar 23.01.2023 21:57

Я не могу проверить ваш запрос с MySQL 5.7 или 8.0. Он возвращает ошибку: "ERROR 3065 (HY000): Expression #1 of ORDER BY clause is not in SELECT list, references column 'test.Accounts_Messages.id' which is not in SELECT list; this is incompatible with DISTINCT". Та же ошибка возвращается MySQL 5.7. Таким образом, либо вы тестируете другой запрос, чем тот, который вы показываете, либо вы на самом деле не используете эти версии MySQL.

Bill Karwin 23.01.2023 22:34

MariaDB не возвращает эту ошибку. Это показывает более общий момент: MariaDB несовместима с MySQL. MariaDB появилась в 2010 году как форк MySQL, но оба продукта изменились настолько, что нам всем следует перестать думать о них как о совместимых. При разработке следует использовать ту же марку и версию, что и в производстве.

Bill Karwin 23.01.2023 22:35

Давайте посмотрим, понимаю ли я, что вы пытаетесь сделать здесь. У вас есть user_id ($login_user_id), и вы хотите получить список информации об учетных записях от всех получателей писем с этим идентификатором пользователя, упорядоченных по последним первым? Верно?

Simon Goater 23.01.2023 23:45

Привет, @BillKarwin! Эту проблему совместимости я решил следующим образом: SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); УСТАНОВИТЬ СЕССИЯ sql_mode = (ВЫБЕРИТЕ ЗАМЕНУ (@ @ sql_mode, 'ONLY_FULL_GROUP_BY', ''));

Jesse Gaspar 24.01.2023 00:05

Спасибо всем, кто пытался мне помочь. Я решил проблему. Я отредактирую пост, объясняя, что я сделал, чтобы решить эту проблему.

Jesse Gaspar 24.01.2023 00:05

@JesseGaspar, пожалуйста, рассмотрите возможность полного удаления блока «EDIT 2 - решено» и опубликуйте его как ответ на свой вопрос. Объясню: Stack Overflow — это не форум, а сайт вопросов и ответов. В нем есть раздел «Вопрос» (Q), в котором вы задавали свой вопрос. И в нем есть раздел ответов (A), в котором другие пользователи (или вы сами) могут ответить на ваш вопрос. См. Могу ли я ответить на свой вопрос. Спасибо!

Vickel 24.01.2023 02:00
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
16
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Решение

Мне удалось решить проблему, выполнив следующую настройку в запросе:

SELECT Accounts.id, Accounts.email, Accounts.name, Accounts.username, Accounts.avatar, Accounts.nivel, Accounts.verification, Accounts_Messages.id
FROM Accounts 
JOIN (
    SELECT m_to, MAX(dt_updated) as max_updated
    FROM Accounts_Messages
    GROUP BY m_to
) last_message
ON Accounts.id = last_message.m_to
JOIN Accounts_Messages 
ON Accounts.id = Accounts_Messages.m_to AND Accounts_Messages.dt_updated = last_message.max_updated
GROUP BY Accounts.id, Accounts_Messages.id
ORDER BY last_message.max_updated DESC;

В CodeIgniter это выглядит так:

<?php
    /*
        With the $this->db->distinct() I make sure that the users shown will not be repeated
    */
    $this->db->distinct();
    $this->db->select(
        array(
            "Accounts.id id",
            "Accounts.email email",
            "Accounts.name name",
            "Accounts.username username",
            "Accounts.avatar avatar",
            "Accounts.nivel nivel",
            "Accounts.verification verification",
            "Accounts_Messages.id acmid",
            "Accounts_Profiles.status online",
            "(SELECT IF(COUNT(ACM.id) > 0, COUNT(ACM.id), null) FROM Accounts_Messages ACM WHERE ACM.m_to = '$login_user_id' AND ACM.m_from = 'Accounts.id' AND ACM.is_read = '0') unread"
        )
    );

    /*
        Here I exclude the $login_user_id from the list, the admin users and also those who have not verified the account
    */
    $this->db->join(
        "Accounts_Profiles",
        "Accounts_Profiles.user_id = Accounts.id", 
        "left"
    );
    $this->db->where(
        array(
            "Accounts.id ! = " => $login_user_id,
            "Accounts.nivel ! = " => 'administrator',
            "Accounts.verification ! = " => 'false'
        )
    );

    /*
        Here, I sort messages by last sent. I check who the logged in user sent the last messages to and list those users
    */
    $this->db->join(
        "(SELECT m_to, MAX(dt_updated) as max_updated FROM Accounts_Messages GROUP BY m_to) last_message", 
        "Accounts.id = last_message.m_to", 
        'inner'
    );
    $this->db->join(
        "Accounts_Messages", 
        "Accounts.id = Accounts_Messages.m_to AND Accounts_Messages.dt_updated = last_message.max_updated", 
        'inner'
    );
    $this->db->group_by(
        "Accounts.id, Accounts_Messages.id"
    );
    $this->db->order_by(
        "last_message.max_updated", 
        "DESC"
    );
?>

Другие вопросы по теме