2011-09-21 56 views
1

我有結構類似SUM對列組

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過程

感謝提前實現

+0

請在提交前預覽您的問題。您選擇文本並使用'{}'圖標格式化爲代碼。同樣爲了格式化SQL,您可以使用http://www.dpriver.com/pp/sqlformat.htm –

+1

這是一團糟,如何格式化該代碼。選擇代碼,按 + G,並輸入正確的換行符和縮進。 – Johan

+1

難怪你對SQL有問題 - 保持整潔並格式化,以便有機會編寫好的查詢 – Bohemian

回答

1

(1)Don't use varchar without length - 但爲什麼你轉換爲varchar呢?

(2)你爲什麼每天按搜索進行分組?我猜這必須是一個SUM是有意義的,這裏是我會怎麼做:

;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]; 

一對夫婦的其他增強功能:

(一)日期不之間使用的/時間,使用> =和<(我離開最後的< =但很可能你的意思是< 9/14或< 9/13)。 (b)不使用區域格式的日期 - '09/13/2010'不取決於語言,日期格式或區域設置的有效日期。 'YYYYMMDD'是在SQL Server中僅用於日期的最安全格式。 (c)嘗試儘可能少地執行計算 - 我將重複計算移入CTE,以便其他計算中的參考可以更簡單。你不需要CTE,你也可以使用子查詢。這也是我將兩次檢查與StartTime和EndTime之間的增量相結合的原因。 (d)您獲取小數的方法相當粗糙 - 增加小數位,轉換爲字符串,取左...

+0

亞倫..非常感謝。從您的回覆中,我學到了很多東西..你是一位真正的老師。我在我的文章中寫道,我是SQL新手,並沒有在這個論壇發佈太多內容,所以不知道格式化。當你知道某事但很難教導時,很容易批評他人。非常感謝。 –

3

你的代碼是可怕的格式化您的文章,所以我打算給你一個一般的答案:

你需要使用GROUP BY條款,然後SUM每個聚合。

因此,像這樣:

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

對不起DEREK ...我是新來這個論壇和學習......謝謝你的更新... –

+0

我在我的查詢德里克使用GROUP和SUM。但它不應該如此。 我已經格式化查詢,以便它可讀 –