Предположим, у меня есть следующая таблица в базе данных SQL Server 2012:
MyTable:
DateCol FkId Sector Value
--------------------------------------------
2018-01-01 1 A 1
2018-01-02 1 A 2
2018-01-03 1 A 3
2018-01-04 1 A 4
2018-01-01 1 B 1
2018-01-04 1 B 4
2018-01-01 1 C 1
2018-01-03 1 C 3
2018-01-04 1 C 4
2018-01-01 2 A 1
...
И я хочу получить средние значения для каждого сектора для конкретного FkId
, , НО НА ОСНОВЕ ОБЩЕГО ЧИСЛА ДАТ, ДОСТУПНЫХ ВСЕГО ДЛЯ ЭТОГО FkId . Это означает, что если бы я хотел получить среднее значение для FkId
= 1 для дат, скажем, 2018-01-01
и 2018-01-10
, мой набор результатов был бы:
Sector AvgVal
---------------------------------
A (1+2+3+4) / 4 = 2.5
B (1+4) / 4 = 1.25
C (1+3+4) / 4 = 2
Другими словами, не делить на число дат, доступных для этого сектора, а делить на общее число дат в таблице для этого диапазона дат для этого FkId
.
Я подумал, что могу сделать это с CTE следующим образом:
DECLARE @FkId INT = 1,
@StartDate DATE = '2018-01-01',
@EndDate DATE = '2018-01-10'
DECLARE @MyTable TABLE
(
DateCol DATE,
FkId INT,
Sector VARCHAR(1),
Value FLOAT
);
INSERT INTO @MyTable (DateCol, FkId, Sector, Value)
VALUES
('2018-01-01', 1, 'A', 1),
('2018-01-02', 1, 'A', 2),
('2018-01-03', 1, 'A', 3),
('2018-01-04', 1, 'A', 4),
('2018-01-01', 1, 'B', 1),
('2018-01-04', 1, 'B', 4),
('2018-01-01', 1, 'C', 1),
('2018-01-03', 1, 'C', 3),
('2018-01-04', 1, 'C', 4),
('2018-01-01', 2, 'A', 1);
WITH NumDates AS
(
SELECT
Sector,
COUNT(DateCol) AS cnt
FROM
@MyTable
WHERE
DateCol BETWEEN @StartDate AND @EndDate
AND FkId = @FkId
GROUP BY
Sector
),
MaxNumDates AS
(
SELECT
MAX(cnt) AS MaxNum
FROM
NumDates
)
SELECT
Sector,
SUM(Value) / MaxNum AS AvgVal
FROM
@MyTable
JOIN
MaxNumDates ON 1 = 1
WHERE
DateCol BETWEEN @StartDate AND @EndDate
AND FkId = @FkId
GROUP BY
Sector, MaxNum
Но я действительно надеюсь, что есть лучший способ. Есть мысли?