我正在使用AdventureWorks2012
示例数据库。
我正在尝试使用datepart
函数计算2006年的季度总交易金额。我需要SEASON
列返回1,2,3,4而不仅仅是3,4和TOTAL
列才能返回值
0, 0, 83537.4000000, 134826.4400000
我很抱歉,如果这看起来令人困惑,那是我第一次使用stackoverflow。请帮忙!
以下是代码:
WITH GROSSINCOME AS
(
SELECT
A.ORDERID,
SUM((B.QTY * B.unitprice * (1 - B.DISCOUNT))) + A.FREIGHT AS TOTAL,
A.orderdate
FROM
SALES.Orders AS A
JOIN
SALES.OrderDetails AS B ON A.orderid = B.orderid
GROUP BY
A.orderid, A.freight, A.orderdate
)
SELECT
DATEPART(QUARTER, orderdate) AS SEASON,
SUM(TOTAL) AS TOTAL
FROM
GROSSINCOME
WHERE
YEAR(orderdate) = '2006'
GROUP BY
DATEPART(QUARTER,orderdate);
答案 0 :(得分:1)
试试这个
WITH GROSSINCOME AS
(
SELECT A.ORDERID, SUM((B.QTY*B.unitprice*(1-B.DISCOUNT))) + A.FREIGHT AS TOTAL,
A.orderdate
FROM SALES.Orders AS A JOIN SALES.OrderDetails AS B
ON A.orderid=B.orderid
GROUP BY A.orderid,A.freight,A.orderdate
)
SELECT T.VAL AS SEASON,
SUM(TOTAL) AS TOTAL
FROM GROSSINCOME
RIGHT JOIN (VALUES(1),(2),(3),(4))as T(VAL) ON T.VAL = DATEPART(QUARTER,orderdate)
WHERE YEAR(orderdate)='2006'
GROUP BY T.VAL;
答案 1 :(得分:0)
只需修复Dark代码,下面的代码就可以了。
WITH GROSSINCOME AS
(
SELECT A.ORDERID,SUM(B.QTY*B.unitprice*(1-B.DISCOUNT)) + A.FREIGHT AS TOTAL,
A.orderdate
FROM SALES.Orders AS A JOIN SALES.OrderDetails AS B
ON A.orderid=B.orderid
WHERE YEAR(A.orderdate)='2006'
GROUP BY A.orderid,A.freight,A.orderdate
)
SELECT T.VAL AS SEASON,
SUM(ISNULL(TOTAL,0)) AS TOTAL
FROM GROSSINCOME
RIGHT JOIN (VALUES(1),(2),(3),(4))as T(VAL) ON T.VAL = DATEPART(QUARTER,orderdate)
GROUP BY T.VAL;
答案 2 :(得分:0)
检查此查询只是修改了你的,它将返回4行,其中有来自1,2,3,4的季节及其总数
;WITH GROSSINCOME AS
(
SELECT
A.ORDERID,SUM((B.QTY*B.unitprice*(1-B.DISCOUNT))) + A.FREIGHT AS TOTAL,
A.orderdate,DATEPART(QUARTER,orderdate) AS season,YEAR(orderdate) orderyear
FROM
SALES.Orders AS A JOIN SALES.OrderDetails AS B
ON A.orderid=B.orderid
GROUP BY A.orderid,A.freight,A.orderdate
)
SELECT
season,SUM(TOTAL) AS TOTAL
FROM GROSSINCOME
WHERE orderyear=2006
GROUP BY season;
答案 3 :(得分:0)
我不鼓励使用公用表表达式(CTE),除非它们有优势或需要。在问题中查询中没有优势或需要CTE。
正如黑暗之夜所表明的那样,解决你的困境就是只有4行,四个季度各占一行。有很多方法可以提供这些行,一个非常简单的联合查询可以做到这一点。这是一个重写,避免使用CTE并对4行使用简单的union all查询。
SELECT
q.n AS Season
, d.total
FROM (
SELECT 1 AS n
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
) AS q
LEFT OUTER JOIN (
SELECT
DATEPART(QUARTER, O.orderdate) AS qtr
, SUM((OD.QTY * OD.unitprice * (1 - OD.DISCOUNT))) + O.FREIGHT AS TOTAL
FROM SALES.Orders AS O
JOIN SALES.OrderDetails AS OD ON O.orderid = OD.orderid
WHERE O.orderdate >= '20060101'
AND O.orderdate < '20070101'
GROUP BY
DATEPART(QUARTER, O.orderdate)
) AS d ON q.n = d.qtr
我还鼓励你不要在where子句中使用函数。我已删除 YEAR(A.orderdate)='2006'的使用,并将其替换为 sargable谓词,以允许访问orderdate列上的索引。
WHERE O.orderdate >= '20060101' AND O.orderdate < '20070101'