2012-01-18 10 views
1

日時フィールドがあり、日付の範囲内の8時から9時までのすべてのレコードを日数で数えたいとします。 2012年1月1日から2012年1月3日まで)。例えばSQLを使用して日付範囲内の特定の時間からレコードを1日ごとに数える方法

、私は以下のデータがある場合:

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) 
+0

RDBMSをあなただけのMS SQL Serverの言ったので、それはのようなより多くのでしょうか?どのバージョン? –

+0

とは08:00:00.000〜08:59:59.999のことですか?つまり、09:00を含めますか? – gbn

+0

SQL Server 2005、およびはい8-8:59:59 – Somebody

答えて

4

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); 
+0

1時間だけフィルタリングすると、その特定の時間内のすべての日数がカウントされます – Somebody

+0

@Somebody:正しく、GROUP BYは「1日あたり」を気にします – gbn

+0

ありがとうございます。それをしてもいいですか? – Somebody

2

最も簡単なコードと最速のコードは、おそらく多くを変え、そしておそらくあなたのデータセットのサイズに依存することになります。

私は、カレンダーとフィルタに参加するのが最も速いと思っています。この場合、これは、ほとんどのインデックス優しいクエリを得て、そのデータの合理的なサイズのため、非常に効率的である必要があり、私が開始する前に、私はカレンダーを作ってあげる、私は永久的なものを提案する...

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 

注:

セクション異なります。 ...

ON yourTable.DateTimeField >= DATEADD(hour, @minHour, calendar.date) 
    AND yourTable.DateTimeField < DATEADD(hour, @maxHour, calendar.date) 
+0

これは、DATEPART()と他の関数を使用して '親和性のあるクエリ'を生成することを避けます。これは、索引または表全体をスキャンするのではなく、索引の関連部分のみが処理されることを意味します。 – MatBailie

0

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) 
関連する問題