2016-02-19 52 views
1

我有一個表格,用於存儲財政年度開始於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。

enter image description here

如何修改查詢這樣當用戶輸入開始日期和結束日期例如 2015年5月1日和2015年7月31日,我將獲得數量結果12640

enter image description here

enter image description here

+1

請在查詢中顯示您的2個表格的表格結構。 – dfundako

回答

4

您可以使用兩種方法來做到這一點。

一種方法是使用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),難以有效地使用。

+0

很好解釋。 –

相關問題