Как считать записи по дням за определенный час в диапазоне дат с использованием SQL - PullRequest
1 голос
/ 18 января 2012

У меня есть поле даты и времени, и я хочу посчитать все записи по дням с 8:00 до 9:00 в диапазоне дат (то есть: с 01.01.2012 по 01.03.2012).

например, если у меня есть следующие данные:

2012-01-01 08:26
2012-01-01 08:40
2012-01-01 09:26
2012-01-01 10:26
2012-01-02 08:06
2012-01-02 09:26
2012-01-02 09:40
2012-01-03 08:30
2012-01-03 10:26

результат должен выглядеть следующим образом:

2012-01-01 2
2012-01-02 1
2012-01-03 1

EDIT: Вот что я получил, используя решение @gbn (оно работает для меня)

SELECT    COUNT(*),  convert(varchar(10),ScanDate,101)
FROM    tblSingleBox (nolock)
WHERE    DATEPART(Hour, scandate) = 8
    and (scandate>='01/03/2012' and scandate<'01/05/2012')
GROUP BY    convert(varchar(10),ScanDate,101) 
order by convert(varchar(10),ScanDate,101)

Ответы [ 3 ]

4 голосов
/ 18 января 2012

SQL Server 2005 и более ранние версии

SELECT
   COUNT(*),
   DATEADD(dd, DATEDIFF(dd, 0, SomeDateTime), 0)
   -- SQL Server 2008: CAST(SomeDateTime AS date)
FROM
   SomeTable
WHERE
   DATEPART(Hour, SomeDateTime) = 8
GROUP BY
   DATEADD(dd, DATEDIFF(dd, 0, SomeDateTime), 0);
   -- SQL Server 2008: CAST(SomeDateTime AS date);

MySQL:

SELECT
   COUNT(*),
   DATE(SomeDateTime)
FROM
   SomeTable
WHERE
   HOUR(SomeDateTime) = 8
GROUP BY
   DATE(SomeDateTime);
2 голосов
/ 18 января 2012

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

Я подозреваю, что самым быстрым будет присоединиться к календарю и фильтровать,В этом случае я создаю календарь перед тем, как начать, но я предлагаю постоянный ...

CREATE TABLE #calendar (
  date AS DATETIME
)
INSERT INTO #calendar SELECT '2011-12-31' UNION ALL SELECT '2012-01-01'
            UNION ALL SELECT '2012-01-02' UNION ALL SELECT '2012-01-03'
            UNION ALL SELECT '2012-01-04' UNION ALL SELECT '2012-01-05'

SELECT
  calendar.date,
  COUNT(*)
FROM
  yourTable
INNER JOIN
  #calendar    AS calendar
    ON  yourTable.DateTimeField >= calendar.date + @minTime
    AND yourTable.DateTimeField <  calendar.date + @maxTime
WHERE
      calendar.date >= @startDate
  AND calendar.date <= @endDate
GROUP BY
  calendar.date

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

ПРИМЕЧАНИЕ:

Разделы calendar.date + @Time могут отличаться.Вы только что сказали MS SQL Server, так что это было бы больше похоже на ...

    ON  yourTable.DateTimeField >= DATEADD(hour, @minHour, calendar.date)
    AND yourTable.DateTimeField <  DATEADD(hour, @maxHour, calendar.date)
0 голосов
/ 18 января 2012

SQL Server 2005

IF OBJECT_ID('tempdb.dbo.#DATES') IS NOT NULL
    DROP TABLE #DATES

CREATE TABLE #DATES
    (   LogDate smalldatetime   )

INSERT INTO #DATES
    (   LogDate )
            SELECT  '2012-01-01 08:26'
UNION SELECT '2012-01-01 08:40'
UNION SELECT '2012-01-01 09:26'
UNION SELECT '2012-01-01 10:26'
UNION SELECT '2012-01-02 08:06'
UNION SELECT '2012-01-02 09:26'
UNION SELECT '2012-01-02 09:40'
UNION SELECT '2012-01-03 08:30'
UNION SELECT '2012-01-03 10:26'
UNION SELECT '2012-01-03 15:26'

DECLARE @nStartHour smallint
DECLARE @nEndHour smallint

SET @nStartHour = 15
SET @nEndHour = 16

SELECT  CONVERT(varchar, LogDate, 101), COUNT(*)
FROM        #DATES
WHERE       DATEPART(hour,LogDate) BETWEEN @nStartHour AND (@nEndHour - 1)
GROUP BY CONVERT(varchar, LogDate, 101)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...