Я создал такую таблицу:
CREATE TABLE #TEMP(RecordDate datetime, First VARCHAR(255), Last VARCHAR(255), Value int)
INSERT INTO #TEMP VALUES('2011-03-01 00:00:00.000','john','smith','10')
INSERT INTO #TEMP VALUES('2011-03-01 00:00:00.000','john','adams','60')
INSERT INTO #TEMP VALUES('2011-03-01 00:00:00.000','john','resig','90')
INSERT INTO #TEMP VALUES('2011-03-01 00:00:00.000','john','balte','95')
INSERT INTO #TEMP VALUES('2011-03-01 01:00:00.000','john','smith','98')
INSERT INTO #TEMP VALUES('2011-03-01 01:00:00.000','john','adams','67')
INSERT INTO #TEMP VALUES('2011-03-01 01:00:00.000','john','resig','24')
INSERT INTO #TEMP VALUES('2011-03-01 01:00:00.000','john','balte','20')
SELECT * FROM #TEMP
DROP TABLE #TEMP
, которая теперь содержит следующие записи:
RecordDate First Last Value
2011-03-01 00:00:00.000 john smith 10
2011-03-01 00:00:00.000 john adams 60
2011-03-01 00:00:00.000 john resig 90
2011-03-01 00:00:00.000 john balte 95
2011-03-01 01:00:00.000 john smith 98
2011-03-01 01:00:00.000 john adams 67
2011-03-01 01:00:00.000 john resig 24
2011-03-01 01:00:00.000 john balte 20
Я пытаюсь получить таблицу, подобную следующей:
RecordDate first Good Bad
2011-03-01 00:00:00.000 john 3 1
2011-03-01 01:00:00.000 john 2 2
То, как я вычисляю «хорошо» и «плохо», состоит в том, чтобы взять MAX
всех людей с именем john
на определенную дату, а затем применить его в качестве фильтра к исходному набору данных на эту конкретную датуи имяТолько значения больше 0.5*MAXValue
считаются Good
.
В таблице результатов имеется 3 правильных значения, поскольку максимальное значение для первой даты было 95
, и только 60,90,95
больше 0.5*95
, поэтому результат имеет (Good,Bad) = (3,1)
.Во втором результате, аналогично, это (2,2)
.
Моя таблица достаточно большая и имеет около 300 миллионов записей, и я не могу понять, с чего начать, чтобы сделать это эффективно.Любые предложения о том, как эффективный способ может выглядеть?
Мой текущий (работающий, но дорогой) подход приведен ниже:
SELECT RecordDate
, FirstName
,
(
SELECT COUNT(*)
FROM #TEMP
WHERE Value > 0.5*(SELECT MAX(Value) FROM #TEMP WHERE RecordDate = A.RecordDate AND FirstName = A.FirstName)
AND RecordDate = A.RecordDate AND FirstName = A.FirstName
) AS Good
,
(
SELECT COUNT(*)
FROM #TEMP
WHERE Value < 0.5*(SELECT MAX(Value) FROM #TEMP WHERE RecordDate = A.RecordDate AND FirstName = A.FirstName)
AND RecordDate = A.RecordDate AND FirstName = A.FirstName
) AS Bad
FROM #TEMP A
GROUP BY RecordDate, FirstName;