Замените переменные mysql на Join

Я использую MySQL 5-enterprise-commercial версию. Я написал ниже 2 запроса, которые я хочу преобразовать в один запрос, используя соединение.

SET @row_number :=0;
SELECT
       @row_number:= case
            when @RId =  r_id then @row_number + 1
                else 1
            end as rnum,
        @RId:=r_id as r_id,
        msg,
        supplier,
        rrtry from (
            SELECT
                a.r_id as r_id,
                mta.message as msg,
                tpr.supplier as supplier,
                trw.retry as rrtry,
                a.createdAt as createdAt,
            FROM sa.nra a,
                sa.nmta mta,
                sa.treq tpr,
                sa.twflw trw
            WHERE tpr.n_r_id = a.r_id
                AND trw.astp = mta.stp
                AND mta.rstatus in ('FAIL')
                AND tpr.p_w_id = trw.id
                AND a.a_mid = mta.id
                AND a.createdAt  BETWEEN now() - interval 30 DAY AND now() 
            ORDER BY  a.r_id
) as  sa
HAVING rnum = 1
ORDER BY createdAt DESC;

По сути, существует несколько записей для r_id, и я хочу получить последнюю запись для определенного r_id, поэтому я использую ORDER BY a_createdAt DESC

Пожалуйста, добавьте несколько строк образцов данных и ожидаемый результат.

The Impaler 02.05.2022 22:04

Какие два запроса?

Hogan 02.05.2022 22:08

Первый запрос — SET @row_number :=0;, а второй — select clause. Я хочу избавиться от использования @row_number и хочу получить тот же результат без использования переменной @row_number

meallhour 02.05.2022 22:12

Не можете ли вы обновиться до MySQL 8.0, чтобы использовать оконные функции для нумерации строк? Это было бы проще. См. пример в моем ответе на Получение последней записи в каждой группе — MySQL

Bill Karwin 02.05.2022 22:22

@meallhour-- хорошо, понятно. Обычно это считается 1 запрос с подзапросом

Hogan 02.05.2022 22:28

Я здесь с Биллом. Почему вы используете такую ​​старую версию MySQL? Такие вещи намного проще в MySQL 8.

Thorsten Kettner 02.05.2022 22:30

Присвоение и чтение одной и той же переменной в одном и том же операторе select является явно неопределенным поведением. (Эффект присваивания в select даже не определен четко.) Таким образом, это не только не имеет гарантированного поведения, но и не сообщает нам, что вы хотите, вы предполагаете интерпретацию кода, которую вы не знаете. т дать, как некоторый порядок оценки. (До 8.0 и оконных функций нужно было написать хранимую процедуру для выполнения такой последовательности назначений.) PS Пожалуйста, уточните с помощью правок, а не комментариев.

philipxy 03.05.2022 01:38
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
8
47
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Соедините запрос с подзапросом, который использует оператор := для установки переменной.

SELECT
    @row_number:= case
        when @RId =  r_id then @row_number + 1
            else 1
        end as rnum,
    @RId:=r_id as r_id,
    msg,
    supplier,
    rrtry 
from (
    SELECT
        a.r_id as r_id,
        mta.message as msg,
        tpr.supplier as supplier,
        trw.retry as rrtry,
        a.createdAt as createdAt
    FROM sa.nra a
    JOIN sa.nmta mta ON a.a_mid = mta.id
    JOIN sa.treq tpr ON tpr.n_r_id = a.r_id
    JOIN sa.twflw trw ON trw.astp = mta.stp AND tpr.p_w_id = trw.id
    WHERE mta.rstatus in ('FAIL')
    ORDER BY  a.r_id
) as  sa
CROSS JOIN (SELECT @row_number := 0) AS vars
HAVING rnum = 1
ORDER BY a_createdAt DESC;

Я заменил кросс-произведение в подзапросе на ANSI JOIN.

Если вы используете MySQL 8.0, вы можете использовать оконные функции RANK() или ROW_NUMBER() вместо пользовательской переменной.

Я добавил createdAt в исходный запрос. Извините, я пропустил это раньше

meallhour 02.05.2022 22:22

Это поведение undefined, см. мои комментарии к вопросу.

philipxy 03.05.2022 01:48

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