我有一个有趣的查询,其聚合订单不正确,因为它按字母数字顺序排列日期,因为它们是字符串(VARCHARS)。它如下。
DROP PROCEDURE dbo.DeploymentReport
GO
CREATE PROCEDURE dbo.DeploymentReport
@Date DATE
AS
BEGIN
SELECT TOP 6 DATENAME(MONTH,DeployDate) + ' - ' + DATENAME(YEAR,DeployDate) AS 'Month',
ISNULL(SUM(CASE WHEN OverallRiskRating = 3 THEN 1 END),0) AS 'High',
ISNULL(SUM(CASE WHEN OverallRiskRating = 2 THEN 1 END),0) AS 'Med',
ISNULL(SUM(CASE WHEN OverallRiskRating = 1 THEN 1 END),0) AS 'Low'
FROM dbo.ChangeEvaluationForm cef
INNER JOIN dbo.Package pac
ON cef.ChangeId = pac.ChangeId
INNER JOIN dbo.SDMTicket sdm
ON pac.PackageId = sdm.PackageId
WHERE DeployDate < @Date
GROUP BY DATENAME(MONTH, DeployDate) + ' - ' + DATENAME(YEAR,DeployDate)
ORDER BY DATENAME(MONTH, DeployDate) + ' - ' + DATENAME(YEAR,DeployDate) DESC
END
GO
DECLARE @DateSelected DATETIME
SET @DateSelected = CONVERT(DATE,'2017-12-30')
EXECUTE dbo.DeploymentReport @Date = @DateSelected;
结果如下所示
正如您所看到的那样,月份按字母顺序排序,而不是按日期排序。
现在我对聚合查询非常残酷,所以我的努力正在改变ORDER BY行,以便以某种方式解析“月份”中的年份和月份。列,以及按年份和月份的订单,而不更改数据返回的结构。
这是完全可能的,还是我认为不可能的方法或错误的思考方式?
答案 0 :(得分:2)
您可以将year(DeployDate)
和month(DepolyDate)
添加到group by子句中,因为您已经在group by子句中使用datename(year, DeployDate)
和datename(month, DeployDate)
它应该不会对所有,除了它允许你在order by子句中使用它们的事实:
CREATE PROCEDURE dbo.DeploymentReport
@Date DATE
AS
BEGIN
SELECT TOP 6 DATENAME(MONTH,DeployDate) + ' - ' + DATENAME(YEAR,DeployDate) AS 'Month',
ISNULL(SUM(CASE WHEN OverallRiskRating = 3 THEN 1 END),0) AS 'High',
ISNULL(SUM(CASE WHEN OverallRiskRating = 2 THEN 1 END),0) AS 'Med',
ISNULL(SUM(CASE WHEN OverallRiskRating = 1 THEN 1 END),0) AS 'Low'
FROM dbo.ChangeEvaluationForm cef
INNER JOIN dbo.Package pac
ON cef.ChangeId = pac.ChangeId
INNER JOIN dbo.SDMTicket sdm
ON pac.PackageId = sdm.PackageId
WHERE DeployDate < @Date
GROUP BY DATENAME(MONTH, DeployDate) + ' - ' + DATENAME(YEAR,DeployDate), Year(DeployDate), Month(DeployDate)
ORDER BY Year(DeployDate) DESC, Month(DeployDate) DESC
END
GO
答案 1 :(得分:1)
将GROUP BY
逻辑转换为使用更“类似日期”分组列的子查询,然后在外部查询中应用TOP
和ORDER BY
:
SELECT TOP 6 DATENAME(MONTH,DeployDate) + ' - ' + DATENAME(YEAR,DeployDate) AS 'Month',
High,Med,Low
FROM (
SELECT DATEADD(month,DATEDIFF(month,0,DeployDate),0) as DeployDate,
ISNULL(SUM(CASE WHEN OverallRiskRating = 3 THEN 1 END),0) AS 'High',
ISNULL(SUM(CASE WHEN OverallRiskRating = 2 THEN 1 END),0) AS 'Med',
ISNULL(SUM(CASE WHEN OverallRiskRating = 1 THEN 1 END),0) AS 'Low'
FROM dbo.ChangeEvaluationForm cef
INNER JOIN dbo.Package pac
ON cef.ChangeId = pac.ChangeId
INNER JOIN dbo.SDMTicket sdm
ON pac.PackageId = sdm.PackageId
WHERE DeployDate < @Date
GROUP BY DATEADD(month,DATEDIFF(month,0,DeployDate),0)
) t
ORDER BY DeployDate DESC
此处,DATEADD(month,DATEDIFF(month,0,DeployDate),0)
将DeployDate
列向下舍入到相关月份的第1天开始的午夜 - 因此同一月内的所有DeployDate
值都会生成相同的值。对此列进行分组相当于对字符串进行分组,但它仍然是datetime
,因此可以在外部ORDER BY
中正确使用。 (并且仍可用于提取外部SELECT
)
答案 2 :(得分:1)
您的时间跨度是有序的,所以我只想在每个中选择一个任意值并执行:
menu.popoverPresentationController?.popoverLayoutMargins = UIEdgeInsets(top: 0, left: -90, bottom: 0, right: -90)
我应该注意到我更喜欢格式YYYY-MM;一个重要原因是它可以正确订购。