SELECT запрос с LIMIT из столбца базы данных в MySQL

У меня есть 2 таблицы:

user          messages
+---------+   +----------------+
|id|credit|   |id|user_id| ... |
+---------+   +----------------+
|01| 05   |   |01| 01    | ... |
|02| 01   |   |02| 01    | ... |
|03| 00   |   |03| 01    | ... |
+---------+   |04| 02    | ... |
              |05| 02    | ... |
              |06| 03    | ... |
              +----------------+

Мне нужно выбрать n сообщения из сообщений , где n = user.credit . Запрос, который я хотел бы выполнить, например:

SELECT * 
FROM user u JOIN messages m ON u.id = m.user_id LIMIT u.credit 
WHERE user in ...;

И должен возвращать строки 01, 02, 03, 04, но не 05, 06.

Я знаю, что я не могу написать LIMIT u.credit , но хочу этого поведения, ограничить количество сообщений, получаемых для каждого пользователя, в зависимости от значения кредитов, которые у них есть (пользовательский 01 whit limit of 5, пользователь 02 с лимитом 1 и т. д.), и я хочу получить все сообщения сразу, чтобы избежать необходимости делать COUNT, а затем SELECT для каждого пользователя.

Я использую MySQL с InnoDB

1
nl ja de
Вы можете указать только константный литерал для LIMIT , а не выражение.
добавлено автор Salman A, источник
Мой плохой, отредактированный вопрос
добавлено автор Xocoatzin, источник
@SalmanA Я знаю, я ищу обходное решение, но избегаю делать несколько запросов.
добавлено автор Xocoatzin, источник
Непосредственно в MySQL лучше всего написать хранимую процедуру, которая выбирает значение u.credit в переменной, а затем строит строку запроса, используя это значение как предел, а затем выполнив процедуру запрос.
добавлено автор newfurniturey, источник
u.id == m.user_id должен быть u.id = m.user_id
добавлено автор inhan, источник

3 ответы

Это решение в простом SQL, без использования переменных:

select user.*, messages.*
from user inner join messages
     on user.id=messages.user_id
where (select count(*) from messages m
       where m.user_id=user.id
       and m.id

Демо

4
добавлено
Он просто работал так, как должен. Благодаря!
добавлено автор Xocoatzin, источник

Боюсь, что это будет медленным:

SELECT u.*
     , m.*
FROM 
    user AS u 
  JOIN
    ( SELECT m1.*, COUNT(*) AS cnt
      FROM messages m1
        JOIN messages m2
          ON  m2.user_id = m1.user_id 
          AND m2.id <= m1.id
      GROUP BY m1.user_id, m1.id 
    ) m 
      ON  m.user_id = u.id 
      AND m.cnt <= u.credit ;

Демо

1
добавлено
Он работал нормально.
добавлено автор Xocoatzin, источник

Есть способ сделать это в SQL, если вы решили.

SELECT u.* 
FROM user u JOIN messages m ON u.id = m.user_id
  inner join user u2 on u2.id <= u.id
WHERE user in ...
GROUP BY u.id
HAVING count(u2.id) < u.credit
0
добавлено
Это кажется хорошим, но MySQL не допускает выражений в предложении LIMIT
добавлено автор Xocoatzin, источник
Я протестировал его, но не вернул правильный набор.
добавлено автор Xocoatzin, источник
Это была ошибка вырезания и вставки. Я отредактировал ответ.
добавлено автор Marlin Pierce, источник
Я вижу, что это должно быть <= вместо <. Я отредактирую свой ответ.
добавлено автор Marlin Pierce, источник
DBA - русскоговорящее сообщество
DBA - русскоговорящее сообщество
1 345 участник(ов)

Общаемся и обсуждаем темы, посвященные DBA, PostgreSQL, Redis, MongoDB, MySQL, neo4j, riak и т.д. См. также: @devops_ru, @kubernetes_ru, @docker_ru, @nodejs_ru Рекомендуем сразу отключить уведомления, чтобы пребывание здесь было полезным и комфортным.

MySQL
MySQL
995 участник(ов)

The group is about MySQL. For code use hastebin.com. Admin: @smlkw

SqlCom.ru - Стиль жизни SQL
SqlCom.ru - Стиль жизни SQL
908 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только MS SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz). Предложения в @sql_ninja

dbGeeks
dbGeeks
545 участник(ов)

Чат про базы данных, их устройство и приемы работы с ними. Разрешаются любые адеватные дискуссии в рамках тематики чата.

SQL_Ninja
SQL_Ninja
340 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz)

Разработка СУБД
Разработка СУБД
143 участник(ов)