每周桶的SQL总和

时间:2016-03-16 11:27:53

标签: sql-server sql-server-2012

这与此处的其他一些问题类似但不够接近我自己有所有信息。我希望使用年限限制日期范围。我不确定他们目前是如何限制数据的,也许是现在一年之前的一年。

我希望一周的开始日是星期一,结束星期日。这些天之间的任何数量,以每个reftype的周数相加,并显示为从星期一开始的日期。

我的数据如下。

+---------+---------+------------------+-------------------------+------------------------+
| Itemid  | RefType | name             | OriginalReqDate         | Qty                    |
+---------+---------+------------------+-------------------------+------------------------+
| B406227 | 8       | Purchase order   | 2016-03-04 00:00:00.000 | 2346.0000000000000000  |
+---------+---------+------------------+-------------------------+------------------------+
| B406227 | 12      | Production order | 2016-03-04 00:00:00.000 | -1295.4000000000000000 |
+---------+---------+------------------+-------------------------+------------------------+
| B406227 | 12      | Production order | 2016-03-07 00:00:00.000 | -3651.6000000000000000 |
+---------+---------+------------------+-------------------------+------------------------+
| B406227 | 8       | Purchase order   | 2016-03-11 00:00:00.000 | 4692.0000000000000000  |
+---------+---------+------------------+-------------------------+------------------------+
| B406227 | 12      | Production order | 2016-03-14 00:00:00.000 | -1397.4000000000000000 |
+---------+---------+------------------+-------------------------+------------------------+
| B406227 | 12      | Production order | 2016-03-21 00:00:00.000 | -958.8000000000000000  |
+---------+---------+------------------+-------------------------+------------------------+
| B406227 | 45      | Formula line     | 2016-03-28 00:00:00.000 | -696.1700000000000000  |
+---------+---------+------------------+-------------------------+------------------------+
| B406227 | 45      | Formula line     | 2016-04-03 00:00:00.000 | -527.5500000000000000  |
+---------+---------+------------------+-------------------------+------------------------+
| B406227 | 8       | Purchase order   | 2016-04-07 00:00:00.000 | 7038.0000000000000000  |
+---------+---------+------------------+-------------------------+------------------------+
| B406227 | 45      | Formula line     | 2016-04-07 00:00:00.000 | -1186.5500000000000000 |
+---------+---------+------------------+-------------------------+------------------------+

我想输出

+---------+---------+------------------------+------------------------+------------------------+------------------------+-----------------------+-----------------------+
| ItemId  | RefType | Name                   | 2016-03-04             | 2016-03-11             | 2016-03-18             | 2016-03-25            | 2016-04-01            |
+---------+---------+------------------------+------------------------+------------------------+------------------------+-----------------------+-----------------------+
| B406227 | 1       | On-hand                | 470.7600000000000000   | NULL                   | NULL                   | NULL                  | NULL                  |
+---------+---------+------------------------+------------------------+------------------------+------------------------+-----------------------+-----------------------+
| B406227 | 8       | Purchase order         | 2346.0000000000000000  | 4692.0000000000000000  | NULL                   | NULL                  | NULL                  |
+---------+---------+------------------------+------------------------+------------------------+------------------------+-----------------------+-----------------------+
| B406227 | 12      | Production order       | -1295.4000000000000000 | -3651.6000000000000000 | -1397.4000000000000000 | -958.8000000000000000 | NULL                  |
+---------+---------+------------------------+------------------------+------------------------+------------------------+-----------------------+-----------------------+
| B406227 | 33      | Planned purchase order | NULL                   | NULL                   | NULL                   | NULL                  | NULL                  |
+---------+---------+------------------------+------------------------+------------------------+------------------------+-----------------------+-----------------------+
| B406227 | 45      | Formula line           | NULL                   | NULL                   | NULL                   | NULL                  | -696.1700000000000000 |
+---------+---------+------------------------+------------------------+------------------------+------------------------+-----------------------+-----------------------+
| B406227 | 99      | Total for B406227      | 1992.1200000000000000  | 2561.7600000000000000  | 1164.3600000000000000  | 205.5600000000000000  | -490.6100000000000000 |
+---------+---------+------------------------+------------------------+------------------------+------------------------+-----------------------+-----------------------+

这是我的尝试:

IF OBJECT_ID('tt', 'U') IS NOT NULL
    DROP TABLE tt;

DECLARE @Columns NVARCHAR(MAX);
DECLARE @SQL NVARCHAR(MAX);

SELECT  @Columns = COALESCE(@Columns + ',', '') + QUOTENAME(ReqDate)
FROM    ( SELECT DISTINCT
                    CAST(ReqDate AS DATE) AS ReqDate
          FROM      SourceTable
        ) AS A
ORDER BY A.ReqDate;

SET @SQL = 'WITH PivotData AS (SELECT DataAreaId, ItemId, RefType, Name, ReqDate, Qty
FROM SourceTable) 
SELECT DataAreaId, ItemId, RefType, Name ' + @Columns + ' 
INTO tt
FROM PivotData

PIVOT
(SUM(Qty)
FOR ReqDate IN (' + @Columns + ')

) AS PivotResult ORDER BY DataAreaId, ItemId, RefType';

EXEC (@SQL);

IF OBJECT_ID('adhoc.V_tt', 'V') IS NOT NULL
    DROP VIEW adhoc.V_tt;

    GO

CREATE VIEW adhoc.V_tt
AS
    ( SELECT    *
      FROM      tt 
    );

2 个答案:

答案 0 :(得分:2)

编辑:动态SQL

通过这个,您可以在星期日动态指向列标题... 注意:根据您的系统文化,您可能需要查看SET DATEFIRST@@DATEFIRST ...

CREATE TABLE #TestTbl(Itemid VARCHAR(100),RefType INT,name VARCHAR(100),OriginalReqDate DATETIME,Qty DECIMAL(8,2));
INSERT INTO #TestTbl VALUES
 ('B406227',8,'Purchase order','2016-03-04T00:00:00.000',2346.0000000000000000)
,('B406227',12,'Production order','2016-03-04T00:00:00.000',-1295.4000000000000000)
,('B406227',12,'Production order','2016-03-07T00:00:00.000',-3651.6000000000000000)
,('B406227',8,'Purchase order','2016-03-11T00:00:00.000',4692.0000000000000000)
,('B406227',12,'Production order','2016-03-14T00:00:00.000',-1397.4000000000000000)
,('B406227',12,'Production order','2016-03-21T00:00:00.000',-958.8000000000000000)
,('B406227',45,'Formula line','2016-03-28T00:00:00.000',-696.1700000000000000)
,('B406227',45,'Formula line','2016-04-03T00:00:00.000',-527.5500000000000000)
,('B406227',8,'Purchase order','2016-04-07T00:00:00.000',7038.0000000000000000)
,('B406227',45,'Formula line','2016-04-07T00:00:00.000',-1186.5500000000000000);

DECLARE @colNames VARCHAR(MAX)=
STUFF
(
    (
        SELECT DISTINCT ',[' + CONVERT(VARCHAR(10),DATEADD(DAY,DATEPART(DW,OriginalReqDate) * (-1),OriginalReqDate),120) + ']'
        FROM #TestTbl
        FOR XML PATH('')
    ),1,1,''
);

DECLARE @cmd VARCHAR(MAX)=
'
SELECT p.*
FROM
(
    SELECT tt.Itemid
          ,tt.RefType
          ,tt.name
          ,SUM(Qty) AS SumQty
          ,CONVERT(VARCHAR(10),DATEADD(DAY,DATEPART(DW,OriginalReqDate) * (-1),OriginalReqDate),120) AS ColumName 
    FROM #TestTbl AS tt
    GROUP BY ItemId,RefType,name,CONVERT(VARCHAR(10),DATEADD(DAY,DATEPART(DW,OriginalReqDate) * (-1),OriginalReqDate),120)
) AS tbl
PIVOT
(
    SUM(SumQty) FOR ColumName IN(' +  @colNames + ')
) AS p
';

EXEC (@cmd);

DROP TABLE #TestTbl;

结果:

Itemid  RefType name             2016-02-28 2016-03-06  2016-03-13  2016-03-20  2016-03-27  2016-04-03
B406227 8       Purchase order   2346.00    4692.00     NULL        NULL        NULL         7038.00
B406227 12      Production order -1295.40   -3651.60    -1397.40    -958.80     NULL         NULL
B406227 45      Formula line      NULL      NULL        NULL        NULL       -1223.72     -1186.55

这是给定样本数据的硬编码方法。如果您希望列可以获得2016-03-04这样的标题,您可以考虑使用动态SQL,或者为正确的输出创建columnName(以及IN() list)。

CREATE TABLE #TestTbl(Itemid VARCHAR(100),RefType INT,name VARCHAR(100),OriginalReqDate DATETIME,Qty DECIMAL(8,2));
INSERT INTO #TestTbl VALUES
 ('B406227',8,'Purchase order','2016-03-04T00:00:00.000',2346.0000000000000000)
,('B406227',12,'Production order','2016-03-04T00:00:00.000',-1295.4000000000000000)
,('B406227',12,'Production order','2016-03-07T00:00:00.000',-3651.6000000000000000)
,('B406227',8,'Purchase order','2016-03-11T00:00:00.000',4692.0000000000000000)
,('B406227',12,'Production order','2016-03-14T00:00:00.000',-1397.4000000000000000)
,('B406227',12,'Production order','2016-03-21T00:00:00.000',-958.8000000000000000)
,('B406227',45,'Formula line','2016-03-28T00:00:00.000',-696.1700000000000000)
,('B406227',45,'Formula line','2016-04-03T00:00:00.000',-527.5500000000000000)
,('B406227',8,'Purchase order','2016-04-07T00:00:00.000',7038.0000000000000000)
,('B406227',45,'Formula line','2016-04-07T00:00:00.000',-1186.5500000000000000);

SELECT p.*
FROM
(
    SELECT tt.Itemid
          ,tt.RefType
          ,tt.name
          ,SUM(Qty) AS SumQty
          ,'w' + CAST(DATEPART(WEEK,OriginalReqDate) AS VARCHAR(MAX)) AS ColumName 
    FROM #TestTbl AS tt
    GROUP BY ItemId,RefType,name,DATEPART(WEEK,OriginalReqDate) 
) AS tbl
PIVOT
(
    SUM(SumQty) FOR ColumName IN(w10,w11,w12,w13,w14,w15)
) AS p

DROP TABLE #TestTbl;

结果:

Itemid  RefType name              w10       w11        w12      w13     w14     w15
B406227 8       Purchase order    2346.00   4692.00    NULL     NULL    NULL    7038.00
B406227 12      Production order  -1295.40  -3651.60   -1397.40 -958.80 NULL    NULL  
B406227 45      Formula line      NULL      NULL       NULL     NULL  -1223.72 -1186.55

答案 1 :(得分:-1)

这是我的尝试......

IF OBJECT_ID('tt', 'U') IS NOT NULL
    DROP TABLE tt;

DECLARE @Columns NVARCHAR(MAX);
DECLARE @SQL NVARCHAR(MAX);

SELECT  @Columns = COALESCE(@Columns + ',', '') + QUOTENAME(ReqDate)
FROM    ( SELECT DISTINCT
                    CAST(ReqDate AS DATE) AS ReqDate
          FROM      SourceTable
        ) AS A
ORDER BY A.ReqDate;

SET @SQL = 'WITH PivotData AS (SELECT DataAreaId, ItemId, RefType, Name, ReqDate, Qty
FROM SourceTable) 
SELECT DataAreaId, ItemId, RefType, Name ' + @Columns + ' 
INTO tt
FROM PivotData

PIVOT
(SUM(Qty)
FOR ReqDate IN (' + @Columns + ')

) AS PivotResult ORDER BY DataAreaId, ItemId, RefType';

EXEC (@SQL);

IF OBJECT_ID('adhoc.V_tt', 'V') IS NOT NULL
    DROP VIEW adhoc.V_tt;

    GO

CREATE VIEW adhoc.V_tt
AS
    ( SELECT    *
      FROM      tt 
    );