Отображение максимальной даты для каждой записи в предложении WHERE IN SQL - PullRequest
0 голосов
/ 09 ноября 2019

Используя MySQL, у меня есть следующая таблица с именем subscriptions, показанная ниже

name,   renewal_date,    national_id
---------------------------------------
ted,     1/2/2010,        A1111R
ben,     1/3/2010,        A145E1
bob,      8/4/2009,       A11C11
kate,     2/2/2010,       A111E1
ted,     12/2/2011,       A1111R
bob,     12/2/2014,       A11C11
ben,     12/2/2016,       A145E1

etc..

В таблице около 150000 записей. Каждый человек может иметь несколько подписок. Я хочу отобразить максимальное / последнее значение renewal_date для каждой записи в списке, предоставленном мне для запроса. Вот мой SQL-оператор:

select d.name, d.renewal_date, d.national_id
from subscriptions d
where renewal_date= (select max(d1.renewal_date) 
                     from subscriptions d1 
                     where d1.national_id = d.national_id IN ('A1111R','A11C11', 'A145E1' ....));

Когда я запускаю запрос в phpmyadmin, он, похоже, не завершается, даже когда записей в предложении IN немного.

Какой лучший способ сделать это? Я должен также сказать, что я еще не эксперт по SQL :-) Заранее спасибо

Ответы [ 2 ]

1 голос
/ 09 ноября 2019

Предполагая, что имена и национальные идентификаторы не меняются для данного человека, вы можете просто использовать агрегацию:

select d.name, max(d.renewal_date), d.national_id
from subscriptions d
where d.national_id in ( . . . )
group by d.name, d.national_id;

Если вы хотите, чтобы все столбцы в строке, наиболее эффективным методом, как правило, является коррелированныйподзапрос с правильным индексом:

select s.*
from subscriptions s
where s.national_id in ( . . . ) and
      s.renewal_date = (select max(s2.renewal_date)
                        from subscriptions s2
                        where s2.national_id = s.nation_id
                       );

Правильный индекс (national_id, renewal_date). На самом деле, это, вероятно, быстрее, чем запрос group by также при многих обстоятельствах.

0 голосов
/ 09 ноября 2019

Вы хотите максимальную дату обновления для имени. Если это так, то все, что вам нужно сделать, это агрегировать:

select name, max(renewal_date)
from subscriptions
group by name
order by name;

Я не знаю, как национал-идентификатор входит в Play. Может ли национальный_ид человека действительно измениться с одной подписки на другую? Или это дефект вашей базы данных?

Вы можете захотеть это:

select name, national_id, max(renewal_date)
from subscriptions
group by name, national_id
order by name, national_id;

или это:

select name, max(renewal_date), any_value(national_id)
from subscriptions
group by name
order by name;

или это:

select *
from subscriptions
where (name, renewal_date) in
(
  select name, max(renewal_date)
  from subscriptions
  group by name
)
order by name;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...