(1) Не используйте varchar без длины - но почему вы все равно конвертируетесь в varchar?
(2) Почему вы группируете по поиску в день? Я предполагаю, что это должна быть сумма, чтобы иметь смысл, вот как я бы это сделал:
;WITH x AS
(
SELECT
[Date] = DATEDIFF(DAY, '19000101', t.StartTime),
DailyMinutes = SUM(DATEDIFF(SECOND, t.StartTime, t.EndTime)),
OrderCount = COUNT(DISTINCT p.PackageDetailID),
SearchesPerDay = SUM(e.SearchesPerDay)
FROM
dbo.ProductTime AS e
INNER JOIN
dbo.PackageDetails AS p
ON e.ProductID = p.ProductID
INNER JOIN
dbo.TaskTime AS t
ON p.PackageDetailID = t.PackageDetailID
WHERE
t.EndTime IS NOT NULL
AND (DATEDIFF(SECOND, t.StartTime, t.EndTime) BETWEEN 1 AND 3599)
AND (t.UserId = '12345')
AND (t.StartTime >= '20100101' AND t.StartTime <= '20100913')
GROUP BY
DATEDIFF(DAY, '19000101', t.StartTime)
)
SELECT
[Date] = DATEADD(DAY, [Date], '19000101'),
DailyMinutes,
OrderCount,
PerOrder = CONVERT(DECIMAL(10,2), (DailyMinutes * 1.0 / OrderCount)),
WeightedOrderCount = CONVERT(DECIMAL(10,2), (100.0 * OrderCount / SearchesPerDay))
FROM
x
ORDER BY
[Date];
Пара других улучшений:
(a) не используйте МЕЖДУ для даты / времени, используйте> = и <(я оставил конец как <=, но, скорее всего, вы имели в виду <9/14 или <9/13). </p>
(b) не используйте региональные форматы для дат - '09 / 13/2010 'не является допустимой датой в зависимости от языка, формата даты или региональных настроек. «ГГГГММДД» - самый безопасный формат для использования в SQL Server только для даты.
(c) попытаться выполнить вычисления как можно меньше раз - я переместил повторные вычисления в CTE, чтобы ссылаться в других вычислениях было намного проще. Вам не нужен CTE, вы также можете использовать подзапрос. Это также причина, по которой я объединил две проверки по дельте между StartTime и EndTime.
(d) ваш метод получения десятичных дробей был довольно грубым - добавление десятичных разрядов, преобразование в строку, взятие левого ...