#sql #max
Вопрос:
У меня есть таблица с такими данными:
пункт | из-за даты | net_avail_qty |
---|---|---|
1 | 03-21 АПРЕЛЯ | 11 |
1 | 05-21 АПРЕЛЯ | -3 |
1 | 01-21 МАЯ | 6 |
1 | 13-21 ИЮНЯ | 8 |
2 | 05-21 АПРЕЛЯ | 99 |
2 | 07-21 МАЯ | 81 |
2 | 11-21 МАЯ | 72 |
2 | 13-21 ИЮЛЯ | 60 |
2 | 23-21 ИЮЛЯ | 55 |
5 | 12-21 АПРЕЛЯ | 22 |
5 | 06-21 МАЯ | 5 |
5 | 14-21 МАЯ | 12 |
Я разобрался с этим запросом:
SELECT item, MAX(due_date)
FROM *table*
where item = '1'
GROUP BY item, TRUNC(due_date, 'MM')
Я понимаю это:
пункт | МАКС(дата рождения) |
---|---|
1 | 05-21 АПРЕЛЯ |
1 | 01-21 МАЯ |
1 | 13-21 ИЮНЯ |
Это частично то, что я хочу, но это ограничивает меня только пунктом 1, и если я попытаюсь добавить net_avail_qty в запрос, я верну все значения-вероятно, потому, что значения net_avai_qty все разные.
То, что я хочу получить в итоге, — это:
пункт | из-за даты | net_avail_qty |
---|---|---|
1 | 05-21 АПРЕЛЯ | -3 |
1 | 01-21 МАЯ | 6 |
1 | 13-21 ИЮНЯ | 8 |
2 | 05-21 АПРЕЛЯ | 99 |
2 | 11-21 МАЯ | 72 |
2 | 23-21 ИЮЛЯ | 55 |
5 | 12-21 АПРЕЛЯ | 22 |
5 | 14-21 МАЯ | 12 |
Как бы я это сделал? Я попытался выполнить подзапросы, но мне не повезло.
Комментарии:
1. Я не вижу разницы между исходной таблицей и данными, которые вы хотите получить в итоге. Вы пытаетесь увидеть общую
net_avail_qty
сумму за месяц?2. Также, пожалуйста, отметьте базу данных, которую вы используете.
3. Таблица, которую я запрашиваю в качестве столбцов item, order_qty, due_date и net_avail_qty (среди прочего) в ней. Происходит много транзакций, и net_avail_qty сохраняет чистый результат, а также вводятся положительные и отрицательные значения order_qty. Значение order_qty является положительным, если покупается больше, и отрицательным, если некоторые продаются. Я хочу найти баланс в net_avail_qty и последнюю дату в этом месяце для каждого элемента. Первоначальный запрос дает мне правильные последние даты. Когда я пытаюсь добавить net_avail_qty в этот запрос, я получаю несколько дат в месяц. Это помогает?
Ответ №1:
Ваш код выглядит как Oracle, если это так, вы можете использовать keep
синтаксис:
SELECT item, MAX(due_date),
MAX(net_avail_qty) KEEP (DENSE_RANK FIRST ORDER BY due_date DESC) as net_avail_qty
FROM *table*
-- WHERE item = 1
GROUP BY item, TRUNC(due_date, 'MM');
Однако чаще всего я бы сказал, что это делается с помощью оконных функций:
SELECT t.*
FROM (SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY item, TRUNC(due_date, 'MM') ORDER BY due_date DESC) as seqnum
FROM T
) t
WHERE seqnum = 1;
Комментарии:
1. Да, это Оракул. Ваше предложение с синтаксисом KEEP сработало идеально! Я тоже хочу попробовать предложение функции Windows, но не уверен, что понимаю, где в этом примере я бы получил net_avail_qty. Я также не уверен, куда поместить имя таблицы. Я ДЕЙСТВИТЕЛЬНО ценю ваше предложение и помощь!!!
2. Я нашел этот код в другом посте. Кажется менее эффективным, чем то, что вы предложили. Хотя это действительно работает. Менее ли эффективно присоединять таблицу к самой себе? ВЫБЕРИТЕ tt.* ИЗ ВНУТРЕННЕГО СОЕДИНЕНИЯ topten tt (ВЫБЕРИТЕ home, MAX(дата-время) В КАЧЕСТВЕ MaxDateTime ИЗ ГРУППЫ topten ПО дому) groupedtt НА tt.home = groupedtt.home И tt.datetime = groupedtt. Максимальное время
3. @MMITSCH . . . Это менее эффективно, чем любое из этих решений.
Ответ №2:
Попробуй это
SELECT
a.item, b.max_due_date, a.net_avail_qty
FROM
table1 a,
(SELECT
item, MAX(due_date) max_due_date
FROM
table1
GROUP BY item , TRUNC(due_date, 'MM')) b
WHERE
a.item = b.item
AND a.due_date = b.max_due_date;
Комментарии:
1. Это сработало, но ответ был не таким, как я ожидал. Похоже, что он получил некоторую информацию, но пропустил несколько месяцев и в некоторых случаях присвоил неправильный net_avail_qty неправильным датам. Сейчас я пытаюсь понять. Спасибо за ваше предложение, и я дам вам знать, что я найду.