开发者

SUM on a Column Group

开发者 https://www.devze.com 2023-04-06 04:51 出处:网络
i have three tables with structure something like tasktime - starttime,endtime,packagedetailid,packageid

i have three tables with structure something like

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

and the query i am using on these is as follows

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) &开发者_开发问答lt; 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)

The OUTPUT is:

**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

But i want to SUM up the "Weightordercount" against the date so that the output is

**date            dailyminutes  ordercount  perorder  weightordercount**

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

i am not a sql expert and need your help if this can be achieved by a Single SQL command or through a Strored Procedure

Thanks in advance


Your code is horribly formatted in your post, so I'm going to give you a general answer:

You need to use a GROUP BY clause and then SUM each of your aggregates.

So something like this:

select date, sum(dailyminutes), sum(ordercount), sum(perorder), sum(weightordercount)
from (yourentirequery) a
group by date
order by date asc


(1) Don't use varchar without length - but why are you converting to a varchar anyway?

(2) Why are you grouping by searches per day? I'm guessing this needs to be a SUM to be meaningful, here is how I would do it:

;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 couple of other enhancements:

(a) don't use BETWEEN for date/time, use >= and < (I left the end as <= but it's likely you either meant < 9/14 or < 9/13).

(b) don't use regional formats for dates - '09/13/2010' is not a valid date depending on language, dateformat or regional settings. 'YYYYMMDD' is the safest format to use in SQL Server for date only.

(c) try to perform calculations as few times as possible - I moved repeated calculations into a CTE so that reference in other calculations can be much simpler. You don't need a CTE, you can also use a subquery. This is also the reason I combined the two checks against the delta between StartTime and EndTime.

(d) your method for getting decimals was rather crude - adding decimal places, converting to a string, taking the left...

0

精彩评论

暂无评论...
验证码 换一张
取 消