由於錯誤說,你不能除非有訂單(TOP
,FOR XML
等)的理由下令子查詢。原因是,僅僅因爲你已經訂購了子查詢,沒有理由認爲這個訂單會保留在你的外部查詢中。 SQL Server基本上告訴你,你的ORDER BY
是毫無意義的,因此無效。
解決方案是簡單地將一個包含月份編號的列添加到您的子查詢s
,然後您可以通過它進行訂購。您還需要明確地說明你的選擇列表,以確保這個新列沒有出現在它:
DECLARE @cols AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(year(TransactionDateTime))
FROM Quotations
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
SET @query =
'SELECT [month], ' + @Cols + '
FROM (
SELECT
left(datename(month,TransactionDateTime),3) as [month],
datepart(month,TransactionDateTime) as [monthNum],
year(TransactionDateTime) as [year],
isnull(count(*),0) as Total
FROM quotations
group by left(datename(month,TransactionDateTime),3), datepart(month,TransactionDateTime), year(TransactionDateTime)
) as s
PIVOT
(
SUM(Total)
FOR [year] IN (' + @cols + ')
) AS QuotationResults
ORDER BY QuotationResults.MonthNum;';
EXECUTE(@query);
附錄
的ISNULL()
不捕獲空值,因爲在使用ISNULL()
的點不存在。 COUNT(*)
將從不返回null,所以你的ISNULL()
實際上是多餘的。
在一個很簡單的例子,如果您有:
TransactionDateTime
----------------------
2015-01-01
2015-02-01
2015-02-01
2014-03-01
要跳過領先一步,你的支點後,你將結束:
Month 2014 2015
------------------------
Jan NULL 1
Feb NULL 2
Mar 1 NULL
所以你最終NULL值,現在回去一步,如果你看看你的聚合後的結果,你有:
Month MonthNum Year Total
-----------------------------------
Jan 1 2015 1
Feb 2 2015 2
Mar 3 2014 1
所以沒有行對於2014年1月或2月,因此SUM(NULL)
將產生NULL
。我建議將所有的聚合都留給pivot函數。所以,你的非動態查詢看起來是這樣的:
SELECT pvt.[Month], pvt.[2014], pvt.[2015]
FROM ( SELECT [Month] = LEFT(DATENAME(MONTH, TransactionDateTime), 3),
[MonthNum] = DATEPART(MONTH, TransactionDateTime),
[Year] = DATEPART(YEAR, TransactionDateTime),
Value = 1
FROM Quotations
) AS t
PIVOT
(
COUNT(Value)
FOR [year] IN ([2014], [2015])
) AS pvt
ORDER BY pvt.MonthNum;
並投入動態SQL:
DECLARE @cols AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(DATEPART(YEAR, TransactionDateTime))
FROM Quotations
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
SET @query =
'SELECT pvt.[Month], ' + @cols + '
FROM ( SELECT [Month] = LEFT(DATENAME(MONTH, TransactionDateTime), 3),
[MonthNum] = DATEPART(MONTH, TransactionDateTime),
[Year] = DATEPART(YEAR, TransactionDateTime),
Value = 1
FROM Quotations
) AS t
PIVOT
(
COUNT(Value)
FOR [year] IN (' + @cols + ')
) AS pvt
ORDER BY pvt.MonthNum;
(
SUM(Total)
FOR [year] IN (' + @cols + ')
) AS QuotationResults
ORDER BY QuotationResults.MonthNum;';
EXECUTE sp_executesql @query;
您是否嘗試過加入'TOP 100%'的選擇? – markpsmith