データベースの統計を作成するプロシージャを作成する必要があります。
まず、作業を「簡素化」するために一時テーブルを作成することにしました。
これには、1日の作業単位(NumCavalier)のすべての関連アクション(FormIdNb)が含まれています。
-- Every action from all units will be stored in this temp table
-- DateHeure = Time of action
-- NumCavalier = ID of working unit
-- FormIdNb = Action type
CREATE TABLE #tmp_DailyMissions (
DateHeure datetime,
NumCavalier nchar(3),
FormIdNb int
)
INSERT INTO #tmp_DailyMissions
SELECT DateHeure, Cavalier.NumCavalier, FormIdNb
FROM ECN4, Cavalier
WHERE (DateHeure BETWEEN @StartTime AND @EndTime) AND (Cavalier.Terminal = @terminal) AND (Cavalier.NumCavalier = ECN4.NumCavalier)
問題は、私が欲しいものを作るように要求することができないことです:
FormIdNb> 3 ==>作業ユニットはその時間間隔でアクティブでした
FormIdNb = 3 ==>作業ユニットはその時間間隔でアイドル状態でした(同じ時間間隔でアクティブでない場合)
FormIdNb <3 ==>作業ユニットはその時間間隔で非アクティブでした(同じ時間間隔でアクティブまたはアイドル状態でない場合)
私はすでにこれを実行しましたが、部分的に機能しますが、前の結合の値は考慮されません(たとえば、作業ユニットが同時にアクティブとアイドルのように見えるなど)。
私はそれを機能させるために多くの変更を加える必要があると思います:
;WITH
time_cte(StartTime, EndTime) AS
(
SELECT @starttime StartTime, DATEADD(mi, 15, @starttime) EndTime
UNION ALL
SELECT EndTime, DATEADD(mi, 15, EndTime) FROM time_cte
WHERE EndTime < @EndTime
)
SELECT StartTime, Count(DISTINCT CavsTerminal_ACTIVE.NumCavalier),
Count(DISTINCT CavsTerminal_IDLE.NumCavalier),
Count(DISTINCT CavsTerminal_INACTIVE.NumCavalier)
FROM time_cte
LEFT OUTER JOIN (
SELECT NumCavalier AS NumCavalier, DateHeure
FROM #tmp_DailyMissions
GROUP BY NumCavalier, FormIdNb, DateHeure
HAVING MAX(FormIdNb) > 3
) CavsTerminal_ACTIVE ON CavsTerminal_ACTIVE.DateHeure BETWEEN time_cte.StartTime AND time_cte.EndTime
LEFT OUTER JOIN (
SELECT NumCavalier AS NumCavalier, DateHeure
FROM #tmp_DailyMissions
GROUP BY NumCavalier, FormIdNb, DateHeure
HAVING MAX(FormIdNb) = 3
) CavsTerminal_IDLE ON (CavsTerminal_IDLE.DateHeure BETWEEN time_cte.StartTime AND time_cte.EndTime)
LEFT OUTER JOIN (
SELECT NumCavalier AS NumCavalier, DateHeure
FROM #tmp_DailyMissions
GROUP BY NumCavalier, FormIdNb, DateHeure
HAVING MAX(FormIdNb) < 3
) CavsTerminal_INACTIVE ON (CavsTerminal_INACTIVE.DateHeure BETWEEN time_cte.StartTime AND time_cte.EndTime)
GROUP BY StartTime
#2を実装しない場合、クエリはおそらく次のようになります。
_WITH time_cte(StartTime, EndTime) AS
(
SELECT
@starttime StartTime,
DATEADD(mi, 15, @starttime) EndTime
UNION ALL
SELECT
StartTime = @starttime,
EndTime = DATEADD(mi, 15, @starttime)
FROM
time_cte
WHERE
EndTime < @EndTime
)
SELECT
t.StartTime,
UnitCount = COUNT(d.NumCavalier)
FROM
time_cte AS t
LEFT OUTER JOIN #tmp_DailyMissions AS d
ON d.DateHeure >= t.StartTime
AND d.DateHeure < t.EndTime
GROUP BY
t.StartTime
;
_
次に、COUNT(d.NumCavalier)
をFormIdNb
の値に基づいて3つの値に分割するために、その値をチェックしますカウント時 –次のように:
_WITH time_cte(StartTime, EndTime) AS
(
SELECT
StartTime = @starttime,
EndTime = DATEADD(mi, 15, @starttime)
UNION ALL
SELECT
EndTime,
DATEADD(mi, 15, EndTime)
FROM
time_cte
WHERE
EndTime < @EndTime
)
SELECT
t.StartTime,
ActiveUnitCount = COUNT(CASE WHEN d.FormIdNb < 3 THEN d.NumCavalier END),
IdleUnitCount = COUNT(CASE WHEN d.FormIdNb = 3 THEN d.NumCavalier END),
InactiveUnitCount = COUNT(CASE WHEN d.FormIdNb > 3 THEN d.NumCavalier END)
FROM
time_cte AS t
LEFT OUTER JOIN #tmp_DailyMissions AS d
ON d.DateHeure >= t.StartTime
AND d.DateHeure < t.EndTime
GROUP BY
t.StartTime
;
_
これは条件付き集計と呼ばれます:ある条件に基づいて結果を集計しています。
このメソッドの魅力の1つは、結果の列セットにCOUNT(d.NumCavalier)
を含めることで、必要に応じて同じ出力で合計数を取得できることです。