0

datetime各行の開始時刻と終了時刻を表す2 つのフィールドを持つ最大 50,000 レコードが与えられた場合、SQL Server クエリを作成して、開始日と終了日の間の任意の時間範囲のバケット ( 30 分、0 ~ 1 時間など)を含むヒストグラムを作成するにはどうすればよいですか? 1 ~ 2 時間、2 ~ 4 時間、4 ~ 8 時間、8 ~ 24 時間、24 ~ 48 時間、48 ~ 72 時間、3 ~ 5 日、7 日以上?

すべてのバケット (この場合は 10) に対してクエリを実行することを回避する賢い方法があることを願っています。私は軽い ORM として LINQ-to-SQL を使用していますが、生の SQL でも問題ありません。

私の素朴なアプローチは、最初にすべてを 60 分ずつバケットに入れ、次にサブクエリを実行して不規則な各バケットを引き出すことです。

編集: LINQCASEでステートメントを生成できることを学んだばかりなので、LINQ バージョンのボーナスポイント。期間テーブルとCASEステートメントの間のパフォーマンスに関する考慮事項はありますか?

4

3 に答える 3

0

これを試して:

SELECT Periods.Period, SUM(Price)
FROM
(
    SELECT '2013-01-01 10:00:00' AS StartDate, '2013-01-01 10:30:00' AS EndDate, 10 AS Price
    UNION ALL
    SELECT '2013-01-01 09:00:00' AS StartDate, '2013-01-01 10:00:00' AS EndDate, 20 AS Price
    UNION ALL
    SELECT '2013-01-01 11:00:00' AS StartDate, '2013-01-01 13:00:00' AS EndDate, 30 AS Price
    UNION ALL
    SELECT '2013-01-01 13:00:00' AS StartDate, '2013-01-01 15:00:00' AS EndDate, 40 AS Price
    UNION ALL
    SELECT '2013-01-01 10:00:00' AS StartDate, '2013-01-01 13:00:00' AS EndDate, 50 AS Price
) AS Prices
INNER JOIN 
(
    SELECT 1 AS Period
    UNION ALL
    SELECT 2 AS Period
    UNION ALL 
    SELECT 3 AS Period
) AS Periods
ON DATEDIFF(HOUR, Prices.StartDate, Prices.EndDate) < Periods.Period
GROUP BY Periods.Period

テーブルでは、開始日と終了日の間の期間を計算し、それを期間 (私が理解しているように-x 軸の値) でテーブルに結合し、これらの期間でグループ化できます。

于 2013-02-08T13:14:45.170 に答える
0

linq アプローチ (アイデアを得るためにほんの数回の間隔で)

var i30m = TimeSpan.FromMinutes(30).TotalMinutes;
var i60m = TimeSpan.FromMinutes(60).TotalMinutes;
var i2h = TimeSpan.FromHours(2).TotalMinutes;

context.Records.Select(t => SqlMethods.DateDiffMinute(t.StartTime, t.EndTime))
      .GroupBy(i => i < i30m
                      ? "0-30 m"
                      : i < i60m
                          ? "30-60 m"
                          : i < i2h
                              ? "1-2 h"
                              : "Long")
      .Select(i => new {i.Key, Count = i.Count()})

SqlMethodsは、linq to sql 用の SQL Server 関数を提供します。

于 2013-02-08T14:35:11.443 に答える
0

持っていたと言う

SomeTable(Key,StartDate,EndDate)

Select Key,DateDiff(minute,StartDate,EndDate) From SomeTable as RawValue

各キーと分の違いが得られます

それで

Select Key,
Case When RawValue < 30 Then "Less than 30 minutes"
Case When RawValue between 30 and 60 then "Less than an hour"
...
else 'Over 7 days' as HistValue
From
(
Select Key,DateDiff(minute,StartDate,EndDate) From SomeTable as RawValue
) RawValues

各キーと差の範囲を提供します

それで

Select HistValue,Count(*) From
(
Select Key,
Case When RawValue < 30 Then "Less than 30 minutes"
Case When RawValue between 30 and 60 then "Less than an hour"
...
else 'Over 7 days' as HistValue
From
(
Select Key,DateDiff(minute,StartDate,EndDate) From SomeTable as RawValue
) RawValues
) UncountedValues

とにかく、頭のてっぺんから、一度に多くを与えてくれませんか。

より一般的な解決策が必要な場合、1 つの方法は期間テーブルを定義することです

例えば

Category        MinMinutes MaxMinutes
"Less than 30"  0         30

ハードコーディングを取り除き、結合を行います

例えば

Inner join Duration On BucketMinutes between MinMinutes and MaxMinutes
于 2013-02-08T13:16:05.797 に答える