Как я могу выбрать / отсортировать даты по интервалам? - PullRequest
1 голос
/ 27 мая 2009

Например:

Если в таблице есть записи типа:

25/06/2009
28/12/2009
19/02/2010
16/04/2011
20/05/2012

Я хочу разделить / выбрать эти даты с интервалом в 6 месяцев, начиная с текущей даты. результат должен быть таким: Через 0-6 месяцев: первая запись Через 7-12 месяцев: вторая запись ...

Будет очень признательно, если вы сделаете это простым, потому что я сделал это очень глупым и сложным, как:

declare variable like t1=curdate()+6 
t2=curdate()+12

...

затем выбирает записи, которые помещаются между curdate () и t1, затем t1 и t2 и т. Д.

Спасибо

г.

Ответы [ 5 ]

1 голос
/ 27 мая 2009

ИСПРАВЛЕНИЕ: Если бы это было задом наперед, нужно использовать модуль, а не целочисленное деление - извините ...

Если MonthCount - это вычисленное значение, которое подсчитывает количество месяцев с определенного декабря 31, а mod - это модуль деления (выведите остаток после деления)

Select [Column list here] 
From Table
Group By Case When MonthCount Mod 12 < 6 
         Then 0 Else 1 End  

Например, в SQL Server вы можете использовать функцию DateDiff

Select [Column list here] 
From Table
Group By Case When DateDiff(month, myDateColumn, curdate) % 12 < 6 
         Then 0 Else 1 End

(в SQL Server знак процента является оператором модуля)

Это сгруппирует все записи в сегменты, каждый из которых содержит данные за шесть месяцев

0 голосов
/ 29 мая 2009

Если вы используете SQL Server:

SELECT *,
    (
        FLOOR
        (
            (
                DATEDIFF(month, GETDATE(), date_column)
                - CASE WHEN DAY(GETDATE()) > DAY(date_column) THEN 1 ELSE 0 END
            ) / 6.0
        ) * 6
    ) AS SixMonthlyInterval
FROM your_table

Если вы используете MySQL:

SELECT *,
    (
        FLOOR
        (
            (
                ((YEAR(date_column) - YEAR(CURDATE())) * 12)
                + MONTH(date_column) - MONTH(CURDATE())
                - CASE WHEN DAY(CURDATE()) > DAY(date_column) THEN 1 ELSE 0 END
            ) / 6.0
        ) * 6
    ) AS SixMonthlyInterval
FROM your_table
0 голосов
/ 27 мая 2009

Не совсем то, что вы пытаетесь выполнить, но вы могли бы использовать функцию DATEDIFF, чтобы различить диапазон каждой записи:

SELECT t.MonthGroup, SUM(t.Counter) AS TotalCount
FROM (    
      SELECT Counter, (DATEDIFF(m, GETDATE(), Date) / 6) AS MonthGroup
      FROM Table
     ) t
GROUP BY t.MonthGroup

Это создаст подзапрос с выражением, которое выражает желаемую группу диапазона дат. Затем он будет сгруппировать подзапрос по этой группе датирования, и вы сможете делать с результатами все, что захотите.

Редактировать: я изменил пример на основе вашего примера.

0 голосов
/ 27 мая 2009

Этот вопрос действительно сбил меня с толку, потому что я не мог придумать простого решения для него. Черт.

Лучшее, чем я мог управлять, - это абсолютная ложь следующих действий: вы создали временную таблицу, вставили в нее «Периоды», присоединились к исходной таблице и сгруппировали ее.

Предположим, что в вашей таблице содержимого есть следующее

ID int
Date DateTime
Counter int

И вы пытаетесь сложить все counter за шесть месяцев

DECLARE @min_date datetime
select @min_date = min(date) from test

DECLARE @max_date datetime
select @max_date = max(date) from test


DECLARE @today_a datetime
DECLARE @today_b datetime
set @today_a = getdate()
set @today_b = getdate()

CREATE TABLE #temp (startdate DateTime, enddate DateTime)

WHILE @today_a > @min_date
BEGIN
    INSERT INTO #temp (startDate, endDate) VALUES (dateadd(month, -6, @today_a), @today_a)
    SET @today_a = dateadd(month, -6, @today_a)
END
WHILE @today_b < @max_date
BEGIN
    INSERT INTO #temp (startDate, endDate) VALUES (@today_b, dateadd(month, 6, @today_b))
    SET @today_b = dateadd(month, 6, @today_b)
END

SELECT * FROM #temp

SELECT 
    sum(counter), 
    'Between ' + Convert(nvarchar(10), startdate, 121) + ' => ' +  Convert(nvarchar(10), enddate, 121) as Period
FROM test t
    JOIN #Temp ht
        ON t.Date between ht.startDate AND ht.EndDate
GROUP BY 
    'Between ' + Convert(nvarchar(10), startdate, 121) + ' => ' +  Convert(nvarchar(10), enddate, 121)

DROP TABLE #temp

Я действительно надеюсь, что кто-то может найти лучшее решение, которое мой мозг явно растаял.

0 голосов
/ 27 мая 2009
SELECT (DATEDIFF(MONTH, thedate, GETDATE()) / 6) AS semester,
       SUM(receipt)
FROM thetable
GROUP BY semester
ORDER BY semester

ключевая идея - группировка и упорядочение по выражению, которое дает вам «семестр».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...