SQL Serverの非標準の日付ベースのヒストグラム
-
06-07-2019 - |
質問
タイムスタンプ付きのユーザーログインデータがあり、何をしたいのかは、年ごとのログインのヒストグラムを取得することですが、年は任意の日付から始まります。たとえば、次のような情報が必要です:
1 May 2005 - 30 Apr 2006 | 525
1 May 2006 - 30 Apr 2007 | 673
1 May 2007 - 30 Apr 2008 | 892
1 May 2006 - 30 Apr 2009 | 1047
最初の列のラベルは重要ではありませんが、日付範囲は重要です。私は海峡の年ごとにそれを内訳できることを知っています:
SELECT YEAR([date]) AS [year], COUNT(*) AS cnt
FROM logins
GROUP BY YEAR([date])
ORDER BY [year]
しかし、それでは必要なデータ範囲が得られません。どうすればこれができますか?
解決
declare @baseDate datetime
set @baseDate = '1 May 2005'
SELECT
datediff(year, @baseDate, [date]) AS YearBucket
,COUNT(*) AS cnt
FROM logins
GROUP BY datediff(year, @baseDate, [date])
ORDER BY datediff(year, @baseDate, [date])
編集-謝罪、あなたは正しいです。ここに修正バージョンがあります(テストテーブルを使用して開始する必要があります...)
create table logins (date datetime, foo int)
insert logins values ('1 may 2005', 1)
insert logins values ('1 apr 2006', 2)
insert logins values ('1 may 2006', 3)
declare @baseDate datetime
set @baseDate = '1 May 2005'
SELECT
datediff(day, @baseDate, [date]) / 365 AS YearBucket
,COUNT(*) AS cnt
FROM logins
GROUP BY datediff(day, @baseDate, [date]) / 365
ORDER BY datediff(day, @baseDate, [date]) / 365
日よりも細かくする場合は、datediff単位を変更します。
編集#2-わかりました、ここにうるう年を処理するより堅牢なソリューションがあります:) 編集3-実際にはこれはうるう年を処理せず、代わりに可変の時間間隔を指定することができます。うるう年の安全なアプローチについては、dateadd(year、1、@baseDate)を使用します。
declare @baseDate datetime, @interval datetime
--@interval is expressed as time above 0 time (1/1/1900)
select @baseDate = '1 May 2005', @interval = '1901'
declare @timeRanges table (beginIntervalInclusive datetime, endIntervalExclusive datetime)
declare @i int
set @i = 1
while @i <= 10
begin
insert @timeRanges values(@baseDate, @baseDate + @interval)
set @baseDate = @baseDate + @interval
set @i = @i + 1
end
SELECT
tr.beginIntervalInclusive,
tr.endIntervalExclusive,
COUNT(*) AS cnt
FROM logins join @timeRanges as tr
on logins.date >= tr.beginIntervalInclusive
and logins.date < tr.endIntervalExclusive
GROUP BY tr.beginIntervalInclusive, tr.endIntervalExclusive
ORDER BY tr.beginIntervalInclusive
他のヒント
別のテーブルで日付範囲を定義する方法を見つけることができる場合は、ラベルと日付の2つの列を選択し、テーブルに応じて次のようなメインクエリから結合します。
Select Count(*) as NoLogons, DateRangeLabel
From logins a
inner join
(
Select
DateRangeLabel, StartDate, EndDate
From tblMyDates
) b
on a.date between b.startdate and b.enddate
Group by DateRangeLabel
所属していません StackOverflow