2010-06-14 45 views
2

我有以下CTE。其目的是提供獨特的月/年對。後面的代碼將使用CTE生成Month/Year對的連接字符串列表。T-SQL - 如何在CTE中限制訂單限制

;WITH tblStoredWillsInPeriod AS 
(
    SELECT DISTINCT Kctc.GetMonthAndYearString(DateWillReceived) Month 
    FROM Kctc.StoredWills 
    WHERE DateWillReceived BETWEEN '2010/01/01' AND '2010/03/31' 
    ORDER BY DateWillReceived 
) 

我省略了GetMonthAndYearString函數的實現,因爲它是微不足道的。

編輯:根據要求由Martin,這裏是周邊代碼:

DECLARE @PivotColumnHeaders nvarchar(MAX) 
--CTE declaration as above--- 
SELECT @PivotColumnHeaders = 
    COALESCE(
    @PivotColumnHeaders + ',[' + Month + ']', 
    '[' + Month + ']' 
) 
FROM tblStoredWillsInPeriod 
SELECT @PivotColumnHeaders 

可悲的是,它似乎T-SQL是永遠領先一步。當我運行這段代碼時,它告訴我我不允許在CTE中使用ORDER BY,除非我也使用TOP(或FOR XML,不管是什麼)。如果我使用TOP,它告訴我我不能使用它與DISTINCT。是的,T-SQL有所有的答案。

任何人都可以想出解決這個問題的方法,它比簡單地削減我的手腕快嗎?我明白,失血過後的死亡可能會令人驚訝地徘徊,我有最後期限要見面。

感謝您的幫助。

大衛

+0

你可以發佈使用CTE的代碼嗎?還有GetMonthAndYearString返回的值的格式?你說你正在嘗試使用它在這裏http://www.kodyaz.com/articles/t-sql-pivot-tables-in-sql-server-tutorial-with-examples.aspx。你知道CTE只是在下一個聲明的範圍內嗎?所以,當你填充@PivotColumnHeaders時,它會超出下一個位的範圍。 – 2010-06-14 11:08:04

+0

GetMonthAndYearString返回格式爲MMM-YYYY的varchar(8)。我知道CTE的範圍限制 - 我現在提供的代碼已經包含在代碼中。 – David 2010-06-14 12:42:41

回答

1

這項工作?

DECLARE @PivotColumnHeaders VARCHAR(MAX) 

;WITH StoredWills AS 
(
SELECT GETDATE() AS DateWillReceived 
UNION ALL 
SELECT '2010-03-14 11:48:07.580' 
UNION ALL 
SELECT '2010-03-12 11:48:07.580' 
UNION ALL 
SELECT '2010-02-12 11:48:07.580' 
), 
tblStoredWillsInPeriod AS 
(
    SELECT DISTINCT STUFF(RIGHT(convert(VARCHAR, DateWillReceived, 106),8), 4, 1, '-') AS MMMYYYY, 
    DatePart(Year,DateWillReceived) AS Year, 
    DatePart(Month,DateWillReceived) AS Month 
    FROM StoredWills 
    WHERE DateWillReceived BETWEEN '2010-01-01' AND '2010-03-31' 
) 


SELECT @PivotColumnHeaders = 
    COALESCE(
    @PivotColumnHeaders + ',[' + MMMYYYY + ']', 
    '[' + MMMYYYY + ']' 
) 
FROM tblStoredWillsInPeriod 
ORDER BY Year, Month 
+0

啊,所以Chris Bednarski提出的將CTE分類出來並在下面的代碼中進行分類的建議是正確的。我只是無法解決如何將排序添加到SELECT ... COALESCE位。謝謝你馬丁! – David 2010-06-14 14:36:22

+0

可以使用DATENAME而不是CONVERT。否則,就像買了一個。 +1 – 2010-06-15 09:38:16

0

您能說明爲什麼您需要訂購CTE中的數據嗎?以及爲什麼您無法使用CTE在查詢中對數據進行排序。記住普通子查詢中的數據也不能排序。

+0

當然。月/年對列表將用於動態數據透視查詢。看看這裏的最後一個例子:http://www.kodyaz.com/articles/t-sql-pivot-tables-in-sql-server-tutorial-with-examples.aspx。 我無法使用CTE在查詢中排序數據,因爲T-SQL告訴我我無法做到!我只是不能使用ORDER BY子句。 – David 2010-06-14 10:39:38

0

那麼呢?

;WITH tblStoredWillsInPeriod AS 
( 
    SELECT DISTINCT Kctc.GetMonthAndYearString(DateWillReceived) Month 
    FROM Kctc.StoredWills 
    WHERE DateWillReceived BETWEEN '2010/01/01' AND '2010/03/31' 
    ORDER BY DateWillReceived 
), 
tblStoredWillsInPeriodOrdered AS 
(
    SELECT TOP 100 PERCENT Month 
    FROM tblStoredWillsInPeriod 
    ORDER BY Month 
) 
+0

你有任何鏈接說,一個CTE中的ORDER BY將始終受到尊重,當它從它的SELECT? (思考Jeff Moden的聲明http://weblogs.sqlteam.com/mladenp/archive/2009/07/28/SQL-Server-2005-Fast-Running-Totals.aspx) – 2010-06-14 11:25:01

+0

謝謝克里斯,我看到你在哪裏來自這裏。我無法按月排序,因爲它是一個varchar字段,不會產生按時間排序的列表(例如,2010年2月將在2010年1月之前)。但是我可以在CTE中構建一個複合年/月字段,然後在下面的代碼中按照它排序。 我會研究這一點。 – David 2010-06-14 12:44:56

+0

不,我無法在下面的代碼中使用ORDER BY,我可以看到... – David 2010-06-14 12:47:23

0
SELECT DISTINCT TOP 100 PERCENT ... 
ORDER BY ... 
+0

你不能使用TOP與DISTINCT ... – David 2010-06-14 12:36:38

+0

謝謝你的擡頭。我錯了。我在'TOP 100 PERCENT'之前放置了'DISTINCT'來解決語法錯誤。 – 2010-06-14 18:12:39

0

而且你認爲你知道T-SQL語法!

原來我不能一起使用TOP和DISTINCT。

這就產生了一個語法錯誤...

SELECT TOP 100 PERCENT DISTINCT... 

,而這絕對是很好...

SELECT DISTINCT TOP 100 PERCENT... 

工作,一出。

一個缺點是您必須在SELECT列表中包含ORDER BY字段,這很可能會干擾您期望的DISTINCT結果。有時候T-SQL讓你在圈子裏跑來跑去。

但現在,我的手腕沒有標記。

+0

啊,雖然我發現這不是語法上有效的,但結果並沒有真正分類! 其他人? – David 2010-06-14 13:51:11