Выберите Уникальное значение из значений, возвращаемых в запросе

#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 неправильным датам. Сейчас я пытаюсь понять. Спасибо за ваше предложение, и я дам вам знать, что я найду.