【问题标题】:Getting quantity between a range of months from 2 date parameters从 2 个日期参数获取一系列月份之间的数量
【发布时间】:2016-02-19 13:11:11
【问题描述】:

我有一张表,其中存储了一家公司的预算数量,该公司的财政年度从 4 月 1 日开始,到次年 3 月 31 日结束。

我有这个查询来提取特定月份的数字。

SELECT SUM(T1.U_Quantity) AS 'YTDBOwnMadeTea'
      FROM [SL_NTEL_DB_LIVE].[dbo].[@U_BUDG_MADETEA] T0
INNER JOIN [SL_NTEL_DB_LIVE].[dbo].[@U_BUDG_MADETEA_ROW] T1 
      ON T0.DocEntry = T1.DocEntry
WHERE T1.U_Month = DATENAME(MONTH, '2015-04-01') AND T0.U_Source = 'NTEL'

现有的报告采用两个参数,即开始日期和结束日期。 (输入日期时间)

下表:月份列的类型为 nvarchar。

如何修改查询,例如当用户输入 StartDate 和 EndDate 时 2015年5月1日和2015年7月31日,我会得到12640的数量结果。

【问题讨论】:

  • 请在查询中显示您的 2 个表的表结构。

标签: sql-server sql-server-2012


【解决方案1】:

您可以使用几种方法来做到这一点。

一种方法是使用PARSE。像这样。

SELECT SUM(T1.U_Quantity) AS 'YTDBOwnMadeTea'
      FROM [SL_NTEL_DB_LIVE].[dbo].[@U_BUDG_MADETEA] T0
INNER JOIN [SL_NTEL_DB_LIVE].[dbo].[@U_BUDG_MADETEA_ROW] T1 
      ON T0.DocEntry = T1.DocEntry
WHERE PARSE((T1.U_Month + CONVERT(VARCHAR(4),YEAR(CURRENT_TIMESTAMP))) as datetime) BETWEEN @StartDate AND @EndDate
    AND T0.U_Source = 'NTEL'

另一种方法是使用数字表将您的月份名称映射到月份编号并在查询中使用它。

;WITH CTE AS (
SELECT 1 as rn UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
),
MonthMap AS
(
SELECT ROW_NUMBER()OVER(ORDER BY rn ASC) as monthnumber FROM CTE
)
SELECT monthnumber,DATENAME(MONTH,DATEFROMPARTS(2016,monthnumber,1)) FROM MonthMap;

然后像这样将它与您的月份表连接起来。

;WITH CTE AS (
SELECT 1 as rn UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
),
MonthMap AS
(
SELECT ROW_NUMBER()OVER(ORDER BY rn ASC) as monthnumber FROM CTE
)
SELECT SUM(T1.U_Quantity) AS 'YTDBOwnMadeTea'
      FROM [SL_NTEL_DB_LIVE].[dbo].[@U_BUDG_MADETEA] T0
INNER JOIN [SL_NTEL_DB_LIVE].[dbo].[@U_BUDG_MADETEA_ROW] T1 
      ON T0.DocEntry = T1.DocEntry
INNER JOIN MonthMap M ON T1.U_Month = DATENAME(MONTH,DATEFROMPARTS(2016,monthnumber,1))
WHERE M.monthnumber BETWEEN DATEPART(MONTH,@StartDate) AND DATEPART(MONTH,@EndDate)
AND T0.U_Source = 'NTEL';

您应该比较这两种方法的性能。 PARSE 使用起来更简单,但很难正确索引。

单独说明,您应该避免将日期或日期部分存储为月份名称,因为它们会占用更多存储空间(甚至更多,因为您使用的是 NVARCHAR),并且很难有效地使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 2021-11-28
    • 2010-09-21
    相关资源
    最近更新 更多