Определить произвольный последний день в месяце через TSQL? - PullRequest
1 голос
/ 16 февраля 2012

В каждой строке данных, с которыми я работаю, у меня есть дата и значение:

f1                            f2 
2012-01-01 00:00:00.000       10
2012-01-10 00:00:00.000       9
2012-02-01 00:00:00.000       19
2012-02-15 00:00:00.000       31

Используя TSQL, мне нужно возвращать каждую строку, содержащую последний ДЕНЬ для конкретных комбинаций год-месяц. Например, в приведенных выше данных мне нужно возвращать вторую и четвертую строки, так как 1/10/2012 содержит " последний «день» хранится в январе-2012, а 15.02.2012 - последний день, зарегистрированный в феврале-2012. Желаемые результаты:

f1                            f2 
2012-01-10 00:00:00.000       9
2012-02-15 00:00:00.000       31

Обратите внимание, что это не так просто, как просто определить "последний день месяца" или "последний рабочий день месяца".

Я подозреваю, что мне нужно использовать какую-то комбинацию GROUP BY, HAVING, которая включает MAX на datepart («день», f1), но я не знаю, как двигаться дальше. Может ли кто-то подтолкнуть меня в правильном направлении?

Ответы [ 3 ]

5 голосов
/ 16 февраля 2012

Предполагается, что SQL Server 2005 или лучше:

DECLARE @t TABLE (f1 DATETIME, f2 INT);

INSERT @t SELECT '2012-01-01',10
UNION ALL SELECT '2012-01-10',9
UNION ALL SELECT '2012-02-01',19
UNION ALL SELECT '2012-02-15',31;

;WITH x AS 
(
  SELECT f1, f2, ROW_NUMBER() OVER (
   PARTITION BY DATEADD(MONTH, DATEDIFF(MONTH, 0, f1), 0) 
   ORDER BY f1 DESC) AS rn
  FROM @t
)
SELECT f1, f2 FROM x
WHERE rn = 1;
3 голосов
/ 16 февраля 2012

Предполагается, как отмечают другие, что значения f1 различны в вашем наборе.

SELECT
    MaxValues.f1,
    Detail.f2
FROM
    (
    SELECT
        DATEPART(year, f1),
        DATEPART(month, f1),
        MAX(f1) AS f1
    FROM
        MyTable
    GROUP BY
        DATEPART(year, f1),
        DATEPART(month, f1)
    ) AS MaxValues
    INNER JOIN MyTable AS Detail ON
        Detail.f1 = MaxValues.f1
0 голосов
/ 17 февраля 2012

или меньше

SELECT f1, f2 
FROM (SELECT f1, f2, MAX(f1) OVER(PARTITION BY YEAR(f1), MONTH(f1)) AS f3 FROM @t) t
WHERE f1 = f3
...