【问题标题】:SQL how to select dates between 2 date parameters as columns in a stored procedureSQL如何选择2个日期参数之间的日期作为存储过程中的列
【发布时间】:2014-12-13 12:45:55
【问题描述】:

我需要编写一个存储过程,它接受 2 个日期参数,汇总该日期的一些数据,然后返回一行,其中的日期作为列。

我不知道从哪里开始。

假设我的存储过程如下所示:

spGetAccountBalanceByDay(DateTime startDate, DateTime endDate)

我希望列名的格式如下:F_{0}{1}{2} 其中 {0} = 年,{1} = 月,{2} =天。

所以对于 2014 年 13 月 12 日的日期,我的专栏将被称为 f_2014_12_13。我有一个具有匹配的动态属性的数据源(因为有问题的网格可以在任何日期范围内运行)

所以在 SQL 存储过程中,我想在 2 个日期之间循环,将每个日期的帐户余额相加,并将当天的数据放入列中。

所以我的表看起来像这样由存储过程返回:

Account Ref | F_2014_12_13 | F_2014_12_14 | F_2014_12_15
------------------------------------------
ABB001        100            150            0

这些查询可以返回一行或多行,我只需要知道我应该在 SQL 中使用什么函数,我知道它可以动态选择列,只是不知道该怎么做。

任何建议将不胜感激。

【问题讨论】:

  • 您使用的是哪个RDBMS
  • SQL Server 2012 R2。现在做一些更多的研究,看起来 Pivot 可能是答案,但我没有使用它
  • 添加样本数据和所需的输出。枢轴是您所需要的
  • 打算试一试...tavislovell.com/…
  • 看来你已经找到答案了。

标签: sql stored-procedures sql-server-2012 dynamic-columns


【解决方案1】:

结合我在互联网上找到的一些东西,这是我想出的解决方案:

DECLARE @Columns VARCHAR(MAX)
DECLARE @StartDate AS DATETIME
DECLARE @EndDate AS DATETIME
DECLARE @Query AS VARCHAR(MAX)

SET @StartDate = '01 Jan 2012'
SET @EndDate = '31 Mar 2012'

;WITH dateRange as
(
    SELECT [Date] = DATEADD(dd, 1, DATEADD(dd, -1,@startDate))
    WHERE DATEADD(dd, 1, @startDate) < DATEADD(dd, 1, @endDate)
    UNION ALL
    SELECT DATEADD(dd, 1, [Date])
    FROM dateRange
    WHERE DATEADD(dd, 1, [Date]) < DATEADD(dd, 1,@endDate)
)

SELECT @Columns = COALESCE(@Columns, '[') + CONVERT(VARCHAR, [Date], 111) + '],['
FROM dateRange
OPTION (maxrecursion 0)

--delete last two chars of string (the ending ',[') and store columns in variable
SET @Columns = SUBSTRING(@Columns, 1, LEN(@Columns)-2)

SELECT @Columns

SET @Query = 
'
 SELECT *
 FROM 
 (
    SELECT 
                [PLSupplierAccount].[SupplierAccountNumber],
                [PLSupplierAccount].[SupplierAccountName],
                [PLPostedSupplierTran].[DueDate],
                [PLPostedSupplierTran].[GoodsValueInAccountCurrency] * [PLPostedSupplierTran].[DocumentToBaseCurrencyRate] AS [Value]
    FROM        [PLPostedSupplierTran]
    INNER JOIN  [PLSupplierAccount]
    ON          [PLSupplierAccount].[PLSupplierAccountID]
    =           [PLPostedSupplierTran].[PLSupplierAccountID]
    WHERE       [PLPostedSupplierTran].[DueDate]>= ''' + CONVERT(VARCHAR(50), @StartDate, 111) + ''' AND [PLPostedSupplierTran].[DueDate]<= ''' + CONVERT(VARCHAR(50), @EndDate, 111) + '''
 ) src
 PIVOT
 (
    SUM([Value])
    FOR src.[DueDate] IN (' + @Columns + ')
 ) AS PivotView
'

EXEC (@Query)

【讨论】:

    猜你喜欢
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    • 2016-01-14
    • 2016-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多