我有三个表格,结构类似
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)
OUTPUT是:
**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 Procedure实现这一点,那么需要您的帮助
提前致谢
答案 0 :(得分:3)
你的帖子中的代码格式很糟糕,所以我会给你一个通用答案:
您需要使用GROUP BY
子句,然后使用SUM
每个聚合。
这样的事情:
select date, sum(dailyminutes), sum(ordercount), sum(perorder), sum(weightordercount)
from (yourentirequery) a
group by date
order by date asc
答案 1 :(得分: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];
其他一些增强功能:
(a)不要将BETWEEN用于日期/时间,请使用&gt; =和&lt; (我把结尾留作&lt; =但它可能意味着&lt; 9/14或&lt; 9/13)。
(b)不要使用区域格式作为日期 - &#39; 09/13/2010&#39;不是有效日期,具体取决于语言,日期格式或区域设置。 &#39; YYYYMMDD&#39;是SQL Server中仅用于日期的最安全的格式。
(c)尝试尽可能少地进行计算 - 我将重复计算移动到CTE中,以便其他计算中的参考可以更简单。您不需要CTE,也可以使用子查询。这也是我将两个检查与StartTime和EndTime之间的增量相结合的原因。
(d)获取小数的方法相当粗糙 - 添加小数位,转换为字符串,左侧...