SQL Server动态数据透视表查询

时间:2016-06-26 13:01:46

标签: sql-server dynamic pivot

我正在创建一个动态数据透视查询,显示给定日期范围内每个客户每周的总NetAmount。问题是在本周内没有添加所有NetAmount 。以下是 tblSampleSalesInvoices 的数据:

enter image description here

这是我的剧本。

CREATE PROCEDURE uspSalesWeeklySummary 
(
    @CustomerId INT,
    @FromDate DATETIME,
    @ToDate DATETIME
)
AS 

SET NOCOUNT ON

DECLARE @Query AS VARCHAR(MAX)
DECLARE @DateStart DATETIME = @FromDate 
DECLARE @tmp TABLE ([Date] VARCHAR(MAX))
DECLARE @Month VARCHAR(MAX)
DECLARE @Day VARCHAR(MAX)
DECLARE @ColumnHeader VARCHAR(MAX)
DECLARE @Headers VARCHAR(MAX)

WHILE DATEADD(WEEK, DATEDIFF(WEEK, '19050101', @DateStart), '19050101') <= DATEADD(WEEK, DATEDIFF(WEEK, '19050101', @ToDate), '19050101')
BEGIN

    SET @month = DATENAME(Month, DATEADD(WEEK, DATEDIFF(WEEK, '19050101', @DateStart), '19050101'))
    SET @day = CAST( DATEPART(DD, DATEADD(WEEK, DATEDIFF(WEEK, '19050101', @DateStart), '19050101')) AS VARCHAR(MAX) ) 

    SET @ColumnHeader = 'Week ' + CAST(DatePart(WEEK,@DateStart) AS VARCHAR(MAX)) + ' - ' + CAST(Year(DATEADD(WEEK, DATEDIFF(WEEK, '19050101', @DateStart), '19050101')) AS VARCHAR(MAX)) + ' - ' + @month + ' - ' + @day

    INSERT INTO @tmp ([Date])
    VALUES (@ColumnHeader)

    SET @DateStart = DATEADD(DD, 7, @DateStart)

END


SELECT @Headers = ISNULL(@Headers + ',','') + QUOTENAME(t.[Date])
FROM @tmp t

SET @Headers = @Headers + ',[Grand Total]'

    SET @Query =
    '
    DECLARE @CustomerId INT = ' + CAST(@CustomerId AS VARCHAR) + '
    DECLARE @FromDate DATETIME = CAST(''' + CAST(@FromDate AS VARCHAR) + ''' AS DATETIME)
    DECLARE @ToDate DATETIME = CAST(''' + CAST(@ToDate AS VARCHAR) + ''' AS DATETIME)
    DECLARE @Headers VARCHAR(MAX) = ''' + CAST(@Headers AS VARCHAR(MAX)) + '''

    SELECT *
    FROM
    (   
    SELECT c.CustomerName AS CustomerName, 
            ''Week '' + CAST(DatePart(WEEK,si.TransactionDate) AS VARCHAR(MAX)) + '' - '' 
            + CAST(Year(DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', si.TransactionDate), ''19050101'')) AS VARCHAR(MAX)) + '' - '' 
            + CAST(DATENAME(Month, DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', si.TransactionDate), ''19050101'')) AS VARCHAR(MAX)) + '' - '' 
            + CAST(DATEPART(DD, DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', si.TransactionDate), ''19050101'')) AS VARCHAR(MAX)) AS Header,
            SUM(si.NetAmount) AS NetAmount
    FROM tblSampleSalesInvoices si
        LEFT OUTER JOIN tblSampleCustomers c ON c.Id = si.CustomerId
    WHERE (si.TransactionDate BETWEEN @FromDate AND DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', DATEADD(DD, 7 , @ToDate)), ''19050101''))
        AND (si.CustomerId = @CustomerId OR @CustomerId = 0)
    GROUP BY c.CustomerName, si.TransactionDate

    UNION ALL

    SELECT c.CustomerName AS CustomerName, 
            ''Grand Total'' AS Header,
            SUM(si.NetAmount) AS NetAmount
    FROM tblSampleSalesInvoices si
        LEFT OUTER JOIN tblSampleCustomers c ON c.Id = si.CustomerId
    WHERE (si.TransactionDate BETWEEN @FromDate AND DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', DATEADD(DD, 7 , @ToDate)), ''19050101''))
        AND (si.CustomerId = @CustomerId OR @CustomerId = 0)
    GROUP BY c.CustomerName

    ) AS BaseData
    PIVOT
    (   
        SUM(NetAmount)
        FOR Header IN (' + @Headers + ') 
    ) AS Pivoting'


EXEC (@Query)


GO

EXEC uspSalesWeeklySummary 0,'01/01/2016','02/01/2016'

在此脚本中,NetAmount的SUM仅为10000,因为从2016年1月1日到2016年2月1日,仅进行了1次交易(TR0002)。但是当我将2015年12月27日和2016年2月1日放在参数中时。它仅显示TR0001的NetAmount而不是TR0001和TR0002的SUM的25000。

enter image description here

1 个答案:

答案 0 :(得分:0)

如果您要查找相对于开始日期的周数,并且可以创建#表,那么这可能适合

    <services>
        <service name="WcfService_REST_SuiviColis.Service1" >
            <endpoint address="" binding="webHttpBinding" contract="WcfService_REST_SuiviColis.IService1"  bindingConfiguration="BasicHttpEndpointBinding" />
        </service>
    </services>

    <behaviors>    
        <serviceBehaviors>
            <behavior name="ServiceBehaviour">
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>           
        </serviceBehaviors>
        <endpointBehaviors>
            <behavior name="web">
                <dataContractSerializer maxItemsInObjectGraph="2147483647" />                   
            </behavior>
        </endpointBehaviors>   
    </behaviors>

   <bindings>
       <webHttpBinding>
        <binding name="BasicHttpEndpointBinding"
                 maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"
           receiveTimeout="00:10:00"
           sendTimeout="00:10:00"
           openTimeout="00:10:00"
           closeTimeout="00:10:00">
            <security mode="TransportCredentialOnly" >
                <transport clientCredentialType="Basic"  />                 
            </security>
        </binding>
    </webHttpBinding>
  </bindings>


<serviceHostingEnvironment multipleSiteBindingsEnabled="false" aspNetCompatibilityEnabled="true">
    <serviceActivations>
        <add
          factory="System.ServiceModel.Activation.WebServiceHostFactory"
            relativeAddress="Service1.svc"
            service="WcfService_REST_SuiviColis.Service1" />
    </serviceActivations>
</serviceHostingEnvironment>

请注意日期是英国本地化的