SQL Server DATEPART

时间:2015-12-11 03:14:23

标签: sql sql-server

我正在使用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);

4 个答案:

答案 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'