Сумма по группе столбцов - PullRequest
1 голос
/ 21 сентября 2011

у меня есть три таблицы со структурой что-то вроде

tasktime - starttime,endtime,packagedetailid,packageid
packagedetailid - packageid,productid, etc
productime - productid and searchesperday

и запрос, который я использую для них, выглядит следующим образом

SELECT CONVERT(varchar, t.StartTime, 111) AS 'Date'
, SUM(DATEDIFF(second, t.StartTime, t.EndTime)) / 60 AS DailyMinutes
, COUNT(DISTINCT p.PackageDetailID) AS OrderCount
, LEFT(CAST(SUM(DATEDIFF(minute, t.StartTime, t.EndTime))
     / (COUNT(DISTINCT p.PackageDetailID) + 0.0000001) AS varchar), 4) AS PerOrder
, LEFT(CAST((COUNT(DISTINCT p.PackageDetailID) * 100)
     / (e.SearchesPerDay + 0.00000001) AS varchar), 4) AS WeightedOrderCount
FROM  ProductTime AS e INNER JOIN dbo.PackageDetails AS p
 WITH (NOLOCK) ON e.ProductID = p.ProductID INNER JOIN 
TaskTime AS t WITH (NOLOCK) ON p.PackageDetailID = t.PackageDetailId
WHERE(t.EndTime IS NOT NULL) 
AND (DATEDIFF(hour, t.StartTime, t.EndTime) < 1) 
AND (DATEDIFF(second, t.StartTime, t.EndTime) > 0) 
AND (t.UserId = '12345') 
AND (t.StartTime BETWEEN '1/1/2010'
AND '9/13/2010')
GROUP BY CONVERT(varchar, t.StartTime, 111), e.SearchesPerDay
ORDER BY CONVERT(varchar, t.StartTime, 111)

ВЫХОД:

**date         dailyminutes  ordercount  perorder  weightordercount**

2010/01/04     104                26    4.03    43.30
2010/01/04     10                  1    9.99     1.24
2010/01/04     19                  8    2.37     8.88
2010/01/04     22                 11    1.99    10.90
2010/01/04     18                  5    3.59     2.77
2010/01/05     49                 17    2.99    28.30
2010/01/05     31                  5    6.39     5.55
2010/01/05     26                  6    4.33     5.99
2010/01/05      8                  4    1.99     3.33

Но я хочу подвести "Weightordercount" к дате так, чтобы на выходе было

**date            dailyminutes  ordercount  perorder  weightordercount**

2010/01/04         173           51     21.97       67.09
2010/01/05         114           32     15.70       43.17

Я не являюсь экспертом по SQL и нуждаюсь в вашей помощи, если это может быть достигнуто с помощью одной команды SQL или процедуры Strored

Заранее спасибо

Ответы [ 2 ]

3 голосов
/ 21 сентября 2011

Ваш код ужасно отформатирован в вашем посте, поэтому я собираюсь дать вам общий ответ:

Вам нужно использовать предложение GROUP BY, а затем SUM каждый из ваших агрегатов.

Вот как то так:

select date, sum(dailyminutes), sum(ordercount), sum(perorder), sum(weightordercount)
from (yourentirequery) a
group by date
order by date asc
1 голос
/ 21 сентября 2011

(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) ваш метод получения десятичных дробей был довольно грубым - добавление десятичных разрядов, преобразование в строку, взятие левого ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...