SQL выбирает максимальную и минимальную даты в разных строках

Спасибо за ваше время! Для каждого пользователя я хочу вывести один столбец, который содержит их самую раннюю дату вступления в силу и последнюю дату окончания, а также другие столбцы из этой и других таблиц (этот материал согласован для каждого пользователя). Ниже приведен формат входных данных.

User   Eff_Date     End_Date    Otherstuff...
----|-------------|------------|---------
001 | 20140101    | 20140106
001 | 20140107    | 99990101
002 | 20140201    | 20140305
002 | 20140306    | 20140319
002 | 20140320    | 99990101
003 | 20140401    | 20140402
004 | 20140501    | 20250901

Это в основном то, что я бы предпочел в результате:

User   Eff_Date     End_Date    Otherstuff...
----|-------------|------------|---------
001 | 20140101    | 99990101
002 | 20140201    | 99990101
003 | 20140401    | 20140402
004 | 20140501    | 20250901

Вот что я пробовал:

SELECT DISTINCT M.user, T.mineffdate, T.maxenddate, A.otherstuff


FROM tbluser M
LEFT JOIN otherstuff A ON A.[user]=M.[user]
INNER JOIN (SELECT user, MAX(m.end_date) as maxenddate, MIN(m.eff_date) as mineffdate FROM tbluser M GROUP BY user) T ON T.user = M.user AND T.maxenddate = m.end_date AND T.mineffdate = M.eff_date

Когда я запустил это, пользователи, такие как 003 и 004 выше, появлялись нормально, но пользователи, такие как 001 и 002, вообще не отображались.

Я довольно новичок в SQL, поэтому я могу сделать очень простую ошибку. Не стесняйтесь, дайте мне знать, если это так. Кроме того, у меня нет контроля над источником данных, поэтому я не могу исправить это в источнике. Единственная причина, по которой я узнал об этом, заключалась в том, что я использовал SQL для вывода каждой пользовательской записи, а затем использовал VBA для сборки записей. К сожалению, это не долгосрочное решение.

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация, и я ценю все, толчка в правильном направлении может быть достаточно, чтобы помочь мне решить эту проблему. Еще раз спасибо за ваше время!


person Wolves    schedule 05.06.2014    source источник
comment
Какую платформу sql вы используете? Отметьте сообщение соответствующим образом с помощью MySQL, SQL Server и т. д.   -  person crthompson    schedule 05.06.2014
comment
Извините, SQL-сервер 2012.   -  person Wolves    schedule 05.06.2014
comment
Ну, другие вещи находятся в той же строке, что и минимальная дата, или максимальная дата. Так что еще вы хотите? С минимальной датой или с максимальной датой? Это проблема, которая у вас есть с пользователем 1 и 2: минимальная дата не находится в той же строке, что и максимальная дата!   -  person Raphaël Althaus    schedule 05.06.2014
comment
Остальное привязано к номеру пользователя; он не будет меняться в зависимости от даты.   -  person Wolves    schedule 05.06.2014


Ответы (4)


Как насчет использования оконных функций?

Попробуй это:

Select distinct t.[user],
Min(t.eff_date) Over (Partition By [user]) as EffDate,
Max(t.End_Date) Over (Partition By [user]) as EndDate,
'Other' as [Other]
From tblUser t

EDIT: хотя имейте в виду, что если даты хранятся в виде строк, MIN/MAX будет работать со строками, а не с датами. Возможно, потребуется преобразовать в Date, если они хранятся в виде строк.

person MAW74656    schedule 05.06.2014
comment
Это выглядит хорошо. Проблема в том, что я получаю повторяющиеся записи, несмотря на то, что я выбрал разные - person Wolves; 05.06.2014
comment
@Wolves, вы не можете получить точные дубликаты с отдельными. Ваша проблема, вероятно, связана с другими вашими объединенными данными, нет? - person Raphaël Althaus; 05.06.2014
comment
Рафаэль, ты прав... проблема с дубликатами вызвана другой колонкой, которая немного отличается. Я удалил его, и это решение, похоже, работает так, как предполагалось... - person Wolves; 05.06.2014
comment
@Wolves - Если это помогло, подумайте о том, чтобы отметить это как лучший ответ. - person MAW74656; 10.06.2014
comment
Готово, извините за это! - person Wolves; 11.06.2014

Это мое быстрое решение проблемы

WITH MinTable As(
SELECT [User],MIN(Eff_Date) Eff_Date  FROM Test GROUP BY [User]),
MaxTable As(
SELECT [User],Max(End_Date) End_Date FROM Test GROUP BY [User])
SELECT MinTable.[User], MinTable.Eff_Date, MaxTable.End_Date FROM MinTable INNER JOIN MaxTable ON MinTable.[User] = MaxTable.[User]

Попробуй это.

person classic_vmk    schedule 05.06.2014

это должно работать:

SELECT M.user, M.mineffdate, M.maxenddate, M.otherstuff, a.otherstuff
FROM (SELECT USER, MAX(m.end_date) as maxenddate, 
                   MIN(m.eff_date) as mineffdate,
                   MIN(otherstuff) AS minotherstuff
      from tbluser
      group by user) M
LEFT JOIN otherstuff A ON A.[user]=M.[user]
person Jayvee    schedule 05.06.2014
comment
ваш подзапрос, кажется, не имеет предложения from. - person Alfred Huang; 05.06.2014
comment
извините, проблема с копипастом :) - person Jayvee; 05.06.2014

Попробуйте использовать предложение where NOT EXISTS, пример может быть не совсем тем, что вам нужно, но показывает предложение, которое может вам помочь.

SELECT M.user, M.Eff_Date, M.End_Date, M.otherstuff
FROM tbluser M
WHERE NOT EXISTS(
  SELECT * FROM tbluser N
  WHERE M.user=N.user AND (N.Eff_Date > M.Eff_Date OR N.Eff_Date = M.Eff_Date AND N.End_Date > M.End_Date)
)
person Alfred Huang    schedule 05.06.2014
comment
Спасибо, я попробовал это, и похоже, что это сработает. Мне нужно провести точное сравнение между выводом SQL и тем, что я знаю, правильно, но ГДЕ НЕ СУЩЕСТВУЕТ, кажется, именно то, что я ищу. Большое спасибо! - person Wolves; 05.06.2014
comment
Но будьте осторожны, мой пример может иметь некоторые проблемы, потому что он экспортирует только результаты, eff_date и eff_date максимальны. - person Alfred Huang; 05.06.2014
comment
Если вы хотите взять первый максимум eff_data и второй максимум enddat, вы должны взять WHERE M.user=N.user AND (N.Eff_Date > M.Eff_Date OR N.Eff_Date = M.Eff_Date AND N.End_Date > M.End_Date) внутри подзапроса, чтобы установить приоритет, чтобы для одного пользователя он всегда экспортировал строку. - person Alfred Huang; 05.06.2014
comment
@Raphaël Althaus Я исправил это. - person Alfred Huang; 05.06.2014
comment
Но это не возвращает правильный min eff_date для пользователей 1 и 2 (ну, для всех пользователей, у которых нет минимальной и максимальной даты в одной строке) - person Raphaël Althaus; 05.06.2014
comment
@ Рафаэль Альтхаус, как и мой предыдущий ответ, я меняю условие. - person Alfred Huang; 05.06.2014