Приплюсовать в подзапросе к LIMIT
Нужно дописать запрос так, чтобы если в таблице action_log присутствуют записи type = 1, то к LIMIT 20 прибавилось бы это количество. То есть, к примеру, если в данной запросе будет 20 строк и из них будет 5 записей type = 1, то LIMIT 20 + 5.
SELECT history.*,
users.id
FROM ( SELECT * FROM `action_log` WHERE action_id > 10 ORDER BY `action_id` DESC LIMIT 20) AS history
LEFT JOIN users ON history.user_id = users.id
ORDER BY `action_id` ASC
Ответы (3 шт):
Подсчитать количество type = 1 из action_log, добавить 20 и записать его в переменную:
SET @typeCount = (
SELECT COUNT(*)
FROM action_log
WHERE
type = 1
);
SET @typeCount = 20 + IFNULL(@typeCount, 0);
А затем применить его в prepared statements:
PREPARE stmt FROM '
SELECT
history.*,
users.id
FROM
(
SELECT *
FROM action_log
WHERE
action_id > 10
ORDER BY
action_id DESC
LIMIT ?
) AS history
LEFT JOIN users ON history.user_id = users.id
ORDER BY
action_id DESC
';
EXECUTE stmt USING @typeCount;
DEALLOCATE PREPARE stmt;
UPDATE:
При подсчете количества можно настроить условие выборки по своему. Подсчет количества с type = 1 будет примерно таким:
SET @typeCount = (
SELECT COUNT(*) AS rowcount
FROM
(
SELECT *
FROM
action_log
LIMIT 20
) h
WHERE
h.type = 1
);
SET @typeCount = 20 + IFNULL(@typeCount, 0);
Ну или можно попробовать выполнить одним select-ом. Но тяжело это воспроизвести без структуры таблиц и данных - примерно так:
SELECT
history.*,
users.id
FROM
(
SELECT *
FROM
(
SELECT
(@row_number := @row_number + 1) rownum,
t.rowcount,
a.*
FROM
action_log a
CROSS JOIN (
SELECT COUNT(*) rowcount
FROM
(
SELECT *
FROM
action_log
LIMIT 20
) h
WHERE
h.type = 1
) t
CROSS JOIN (
SELECT @row_number := 0
) n
WHERE
action_id > 10
) l
WHERE
l.rownum <= l.rowcount + 20
) history
LEFT JOIN users ON history.user_id = users.id
ORDER BY
action_id DESC
Вот как-то так:
WITH
cte1 AS (
SELECT *, users.id
FROM `action_log`
LEFT JOIN users ON history.user_id = users.id
WHERE action_id > 10
AND type <> 1
ORDER BY `action_id` DESC LIMIT 20
),
cte2 AS (
SELECT *, users.id
FROM `action_log`
LEFT JOIN users ON history.user_id = users.id
WHERE action_id > 10
AND type = 1
AND action_id > (
SELECT MIN(action_id)
FROM cte1
)
)
(TABLE cte1)
UNION ALL
(TABLE cte2)
ORDER BY `action_id` ASC
cte1 выбирает 20 записей с type <> 1.
cte2 выбирает все записи с type = 1, находящиеся между записями, выбранными в cte1.
Внешний запрос объединяет эти выборки и выполняет финальную сортировку.
Не совсем точно, но можно так
SELECT history.*, users.id,users.username
FROM
( select *
from(
SELECT *
FROM action_log
WHERE action_id > 10 and action_type<>1
ORDER BY action_id DESC LIMIT 20
)t1
union all
select * from(
select *
from action_log
where action_id > 10 and action_type=1
ORDER BY action_id DESC LIMIT 20
)t2
) AS history
LEFT JOIN users ON history.user_id = users.id
ORDER BY action_id ASC