在本教程的this部分中使用Microsoft SQL Server 2012的AdventureWorks2012数据库时,我想添加到示例中,并了解如何使用此查询的变体:
USE AdventureWorks2012;
GO
SELECT
DATEDIFF(dd,DueDate,EndDate) AS 'Days Late',
COUNT(WorkOrderID) AS 'Late Orders',
(COUNT(WorkOrderID) / SUM(COUNT(WorkOrderID)) AS '% of Late Orders'
FROM Production.WorkOrder
WHERE DueDate < EndDate
GROUP BY DATEDIFF(dd,DueDate,EndDate)
ORDER BY DATEDIFF(dd,DueDate,EndDate);
要使此表中“延迟订单的百分比”给出延迟一定天数的计数并将其除以所有延迟的订单,它应如下所示:
----------------------------------------
|Days Late|Late Orders|% of Late Orders|
----------------------------------------
|21 |784 |10 |
|18 |1285 |14 |
----------------------------------------
我已尝试过此查询的多个变体,查看了几个相关的StackOverflow问题,但无法在不收到错误消息的情况下使此表正常工作。 This问题让我最接近,但结果却没有了。
感谢您的帮助。
答案 0 :(得分:2)
问题在于,由于您使用的是GROUP BY
语句,因此所有的聚合函数都在您的子组上运行。您需要单独计算&#34;所有迟到的订单的值&#34;为了获得所有延迟订单的价值而不是具有给定延迟的所有延迟订单,可能使用CTE。
也许是这样的:
USE AdventureWorks2012;
GO
;WITH late (num_late_orders)
AS
(
SELECT COUNT(WorkOrderID)
FROM Production.WorkOrder
WHERE DueDate < EndDate
)
SELECT
DATEDIFF(dd,DueDate,EndDate) AS 'Days Late',
COUNT(WorkOrderID) AS 'Late Orders',
(CAST(COUNT(WorkOrderID) AS decimal(14, 3)) / CAST(MAX(late.num_late_orders) AS decimal(14, 3))) AS '% of Late Orders'
FROM Production.WorkOrder
CROSS JOIN late
WHERE DueDate < EndDate
GROUP BY DATEDIFF(dd,DueDate,EndDate)
ORDER BY DATEDIFF(dd,DueDate,EndDate);
您可能会对MAX()
late.num_late_orders
周围GROUP BY
的原因感到困惑。原因是由于该值未包含在{{1}}子句中,因此必须将其包含在聚合语句中,即使该值在整个查询中保持不变。
答案 1 :(得分:1)
试试这个:
SELECT DATEDIFF(dd,DueDate,EndDate) AS 'Days Late',
COUNT(WorkOrderID) AS 'Late Orders',
(COUNT(WorkOrderID)*1.0 / (select count(1) as TotalLateOrders FROM Production.WorkOrder
WHERE DueDate < EndDate))
AS '% of Late Orders'
FROM Production.WorkOrder
WHERE DueDate < EndDate
GROUP BY DATEDIFF(dd,DueDate,EndDate)
ORDER BY DATEDIFF(dd,DueDate,EndDate);
我乘以1.0除以花车,你也可以在之前的回答中做到这一点