Я использую 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
Какие два запроса?
Первый запрос — SET @row_number :=0;
, а второй — select clause
. Я хочу избавиться от использования @row_number
и хочу получить тот же результат без использования переменной @row_number
Не можете ли вы обновиться до MySQL 8.0, чтобы использовать оконные функции для нумерации строк? Это было бы проще. См. пример в моем ответе на Получение последней записи в каждой группе — MySQL
@meallhour-- хорошо, понятно. Обычно это считается 1 запрос с подзапросом
Я здесь с Биллом. Почему вы используете такую старую версию MySQL? Такие вещи намного проще в MySQL 8.
Присвоение и чтение одной и той же переменной в одном и том же операторе select является явно неопределенным поведением. (Эффект присваивания в select даже не определен четко.) Таким образом, это не только не имеет гарантированного поведения, но и не сообщает нам, что вы хотите, вы предполагаете интерпретацию кода, которую вы не знаете. т дать, как некоторый порядок оценки. (До 8.0 и оконных функций нужно было написать хранимую процедуру для выполнения такой последовательности назначений.) PS Пожалуйста, уточните с помощью правок, а не комментариев.
Соедините запрос с подзапросом, который использует оператор :=
для установки переменной.
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
в исходный запрос. Извините, я пропустил это раньше
Это поведение undefined, см. мои комментарии к вопросу.
Пожалуйста, добавьте несколько строк образцов данных и ожидаемый результат.