Исключить самую последнюю дату при группировке по атрибуту через JOIN

Я хочу исключить самую последнюю дату из результатов моего запроса SQL. Я провел небольшое исследование по этому вопросу и могу найти только примеры, в которых они GROUP BY являются атрибутами в исходной таблице. Я GROUP BY атрибут в объединенной таблице.

Это пара решений, которые я пробовал, но мне трудно адаптировать их решение к моему запросу из-за моего JOIN.

Вот где я сейчас нахожусь (псевдозапрос ниже). Я предполагал, что могу просто изменить IN на NOT IN и тем самым исключить дату MAX, но это не кажется правильной логикой:

SELECT t2.sid
,t1.date
FROM dbo.table1 t1 
LEFT JOIN dbo.table2 t2 ON t1.id = t2.id 
WHERE t1.num = 000
AND t2.sid IS NOT NULL
AND t2.sid NOT LIKE '%#########%'
AND t1.date NOT IN (
    SELECT MAX(t1a.date)
    FROM dbo.table1 t1a
    WHERE t1a.id = t1.id
)
GROUP BY t2.sid,t1.date

Любое понимание очень ценится. Пожалуйста, дайте мне знать, если я могу предоставить дополнительную информацию. Спасибо!

Зачем ты вообще используешь GROUP BY? Здесь нет никакой агрегации.

Thom A 11.07.2024 16:48

Думаю, как альтернатива DISTINCT

Kliment Merzlyakov 11.07.2024 16:48

Я не знаю, можно ли использовать NOT IN в таком коррелированном подзапросе. Может быть? Для иллюстрации: NOT EXISTS — это то, что вы видите чаще всего. бывший. WHERE NOT EXISTS (SELECT 1 FROM dbo.table1 t1a WHERE t1.id = t1a.id GROUP BY t1a.id HAVING t1.date = max(t2.date)) Хотя на практике я бы использовал RANK().

Error_2646 11.07.2024 16:57
NOT IN можно использовать для подзапроса @Error_2646 . Хотя IN в этом примере немного бессмысленен, так как подзапрос вернет набор данных из одного столбца и строки, поэтому с таким же успехом можно использовать !=.
Thom A 11.07.2024 16:58

@Error_2646: разрешено иметь коррелированный подзапрос с [NOT] IN, но считается хорошим стилем использовать коррелированные подзапросы с [NOT] IEXISTS и некоррелированные подзапросы с [NOT] IN.

Thorsten Kettner 11.07.2024 16:59

@ThomA, ты прав. Если не использовать GROUP BY, результат будет тот же. Однако я хотел бы включить date в свои результаты. Единственный способ, которым я могу это сделать, — это включить MAX в мое SELECT заявление. Но, конечно, я хочу исключить MAX. Так что, если есть способ сделать это без использования GROUP BY, то это здорово. Мне просто нужны даты, сгруппированные по t2.sid

Crimp 11.07.2024 17:01

Разве вы не можете просто использовать Получить 1 верхнюю строку каждой группы? Сменить = на != не составляет большого труда.

Thom A 11.07.2024 17:02

Я не слишком знаком с WITH. Когда я трансформирую это решение в соответствии со своими целями, я получаю сообщение об ошибке: «Столбец «id» был указан несколько раз из «cte». Может быть, вы знаете, что это значит? Я поставил JOIN в том месте, где обозначен PARTITION.

Crimp 11.07.2024 17:09

— Может, ты знаешь, что это значит? Буквально это означает то, что написано: у вас есть более двух столбцов, которые вы назвали id в своем CTE.

Thom A 11.07.2024 17:24
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
9
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я считаю, что для этого вы можете использовать оконную функцию RANK(), тогда вы, вероятно, сможете удалить предложение GROUP BY/DISTINCT.

SELECT sid, date FROM (
SELECT t2.sid
, t1.date
, RANK() OVER(ORDER BY t1.date DESC) AS row_num
FROM dbo.table1 t1 
LEFT JOIN dbo.table2 t2 ON t1.id = t2.id 
WHERE t1.num = 000
AND t2.sid NOT LIKE '%#########%'
) as date_ranked_by_id
WHERE date_ranked_by_id.row_num != 1

Я использовал это и получаю некоторые ошибки в SELECT sid, date FROM и дополнительно в WHERE row_num != 1. Я получаю довольно двусмысленную ошибку: «Неправильный синтаксис рядом с ключевым словом «ГДЕ». хотя у меня красный цвет начинается с sid и date.

Crimp 11.07.2024 17:04

@Crimp Попробуйте использовать псевдоним для подзапроса, так что ) as date_ranked_by_id WHERE date_ranked_by_id.row_num != 1

Error_2646 11.07.2024 17:10

Кажется, это удалось! Спасибо @Error_2646

Crimp 11.07.2024 17:15

@Crimp Возможно, ты захочешь ROW_NUMBER не RANK

Charlieface 11.07.2024 17:29

Ну, оказывается, у меня проблемы RANK и ROW_NUMBER. Когда я первоначально тестировал это решение, я дополнительно квалифицировался t2.sid по конкретному id. При такой квалификации будет исключена самая последняя дата. Но когда я убираю эту квалификацию (беру ВСЕ sid), включается самая последняя дата. Понимание того, почему?

Crimp 11.07.2024 17:35

Вам нужно удалить самую последнюю дату для каждого sid? Допустим, у sid = 1 самая последняя дата — 1 июля 2024 г., а у sid = 2 — 02 июля 2024 г.; в этом случае вы хотите удалить обе даты?

Kliment Merzlyakov 11.07.2024 17:41

Ты прав!

Crimp 11.07.2024 17:42

Тогда это легко :) Просто добавьте пункт PARTITION BY в РАНГ. RANK() OVER(PARTITION BY t2.sid ORDER BY t1.date DESC) AS row_num

Kliment Merzlyakov 11.07.2024 17:44

Ты мужчина! Ценю вашу помощь!

Crimp 11.07.2024 17:50

Другие вопросы по теме