Какие пользователи заполнили список: Как мне сделать запрос за несколько шагов? - PullRequest
0 голосов
/ 08 мая 2019

У меня есть списки, идентифицированные как list_id.

В каждом списке есть элементы, обозначенные item_id, упорядоченные по position_int и присвоенные вышеупомянутому list_id.

Теперь у меня есть таблица с именем completed_items. Содержит запись для каждого item_id, который завершил каждый user_id. Для резервирования position_int и list_id также находятся в каждом ряду. Если строка существует, элемент был завершен пользователем. В противном случае запись не существует.

Как я могу узнать, какие user_id имеют полностью завершены какие list_id? В частности, мне интересно, есть ли ОДИН запрос mySQL, который я могу использовать для получения этого набора данных.

enter image description here

Я думаю из соображений удобства и, возможно, из-за производительности, я создам таблицу completed_lists, содержащую list_id и user_id каждого списка, который был полностью заполнен.

Кажется достаточно простым, чтобы я мог создать такой набор данных одним махом, вместо того, чтобы входить и циклически проходить более миллиона вложенных циклов.

Вот мой текущий подход:

FOREACH list_id{

      array_of_items = [all, items, from, list, id];

      FOREACH user_id{
        users_items = [];
        push items into users_items
        if length of array_of_items and users_items is the same
        then create a row in completed_lists
      }

}

Причина, по которой мне не нравится этот подход, заключается в том, что я делаю много отдельных запросов к БД (получаю каждый элемент, получаю каждый идентификатор пользователя) и многократно повторяю цикл. Есть ли лучший способ?

1 Ответ

1 голос
/ 08 мая 2019

Хорошим подходом может быть использование count (*) и GROUP BY.Таким образом, вы получаете счетчик количества строк ответов на пользователя в каждом списке в заполненной таблице, а затем присоединяетесь к подзапросу, который дает вам общее количество элементов в списке.

Примерно так:

select user_id, c.list_id, count(user_id) as list_count, case when item_total-count(user_id)=0 then 'Complete' else 'Incomplete' end as list_status 
from completed c
left join (select list_id, count(*) as item_total from items group by list_id) aa on aa.list_id=c.list_id
group by user_id, c.list_id, item_total

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

Если у вас есть какая-то временная меткаили индекс, вы могли бы использовать diff_rank, чтобы получить первый элемент по дате на пользователя в списке, например.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...