Максимальный групповой
У меня есть таблица, из которой я пытаюсь получить последнюю позицию для каждой безопасности:
Таблица:
Мой запрос для создания таблицы: SELECT id, security, buy_date FROM positions WHERE client_id = 4
+-------+----------+------------+
| id | security | buy_date |
+-------+----------+------------+
| 26 | PCS | 2012-02-08 |
| 27 | PCS | 2013-01-19 |
| 28 | RDN | 2012-04-17 |
| 29 | RDN | 2012-05-19 |
| 30 | RDN | 2012-08-18 |
| 31 | RDN | 2012-09-19 |
| 32 | HK | 2012-09-25 |
| 33 | HK | 2012-11-13 |
| 34 | HK | 2013-01-19 |
| 35 | SGI | 2013-01-17 |
| 36 | SGI | 2013-02-16 |
| 18084 | KERX | 2013-02-20 |
| 18249 | KERX | 0000-00-00 |
+-------+----------+------------+
Я возился с версиями запросов на основе этой страницы, но я не могу получить результат, который я ищу.
Вот что я пытался:
SELECT t1.id, t1.security, t1.buy_date
FROM positions t1
WHERE buy_date = (SELECT MAX(t2.buy_date)
FROM positions t2
WHERE t1.security = t2.security)
Но это просто возвращает меня:
+-------+----------+------------+
| id | security | buy_date |
+-------+----------+------------+
| 27 | PCS | 2013-01-19 |
+-------+----------+------------+
Я пытаюсь получить максимальную/последнюю дату покупки для каждой безопасности, поэтому результаты будут иметь одну строку для каждой безопасности с самой последней датой покупки. Любая помощь приветствуется.
EDIT: Идентификатор позиции должен быть возвращен с максимальной датой покупки.
Ответы
Ответ 1
Вы можете использовать этот запрос. Вы можете добиться результатов на 75% меньше времени. Я проверил с большим набором данных. Sub-Queries занимает больше времени.
SELECT p1.id,
p1.security,
p1.buy_date
FROM positions p1
left join
positions p2
on p1.security = p2.security
and p1.buy_date < p2.buy_date
where
p2.id is null;
SQL-Fiddle ссылка
Ответ 2
Вы можете использовать подзапрос, чтобы получить результат:
SELECT p1.id,
p1.security,
p1.buy_date
FROM positions p1
inner join
(
SELECT MAX(buy_date) MaxDate, security
FROM positions
group by security
) p2
on p1.buy_date = p2.MaxDate
and p1.security = p2.security
См. SQL Fiddle with Demo
Или вы можете использовать следующее с предложением WHERE
:
SELECT t1.id, t1.security, t1.buy_date
FROM positions t1
WHERE buy_date = (SELECT MAX(t2.buy_date)
FROM positions t2
WHERE t1.security = t2.security
group by t2.security)
Смотрите скрипт SQL с демонстрацией
Ответ 3
Это делается с помощью простой группы. Вы хотите группировать по ценным бумагам и получать максимальную сумму buy_date. SQL:
SELECT security, max(buy_date)
from positions
group by security
Обратите внимание, что это быстрее, чем bluefeet answer, но не отображает ID.
Ответ 4
В ответ на @bluefeet есть еще два способа получить желаемые результаты - и первый, вероятно, будет более эффективен, чем ваш запрос.
Я не понимаю, почему вы говорите, что ваш запрос не работает. Это выглядит очень хорошо и возвращает ожидаемый результат. Протестировано при SQL-Fiddle
SELECT t1.id, t1.security, t1.buy_date
FROM positions t1
WHERE buy_date = ( SELECT MAX(t2.buy_date)
FROM positions t2
WHERE t1.security = t2.security ) ;
Если проблемы возникают, когда вы добавляете условие client_id = 4
, то это потому, что вы добавляете его только в одно предложение WHERE
, пока вы должны добавить его в оба:
SELECT t1.id, t1.security, t1.buy_date
FROM positions t1
WHERE client_id = 4
AND buy_date = ( SELECT MAX(t2.buy_date)
FROM positions t2
WHERE client_id = 4
AND t1.security = t2.security ) ;
Ответ 5
select security, max(buy_date) group by security from positions;
- все, что вам нужно, чтобы получить максимальную дату покупки для каждой безопасности (когда вы говорите вслух, что вы хотите от запроса, и вы включаете фразу "для каждого x", вы, вероятно, хотите, чтобы группа была на x)
Когда вы используете group by
, все столбцы в выбранном элементе должны быть либо столбцами, которые были сгруппированы, либо агрегатами, поэтому, если, например, вы хотели включить идентификатор, вам, вероятно, придется использовать подобный подзапрос к тому, что у вас было до этого, так как, похоже, не существует какой-либо совокупности, которую вы можете разумно использовать в идентификаторах, а другая группа будет давать вам слишком много строк.