2010-03-11 41 views
3

我需要顯示日期列表,我有一個表SQL獲得的日期列表,以及天及沒有經過複製

SELECT mydate AS MyDate, 1 AS DateType 
FROM myTable 
WHERE myTable.fkId = @MyFkId; 

2010年1月1日 - 1
2010年1月2日 - 1
2010年1月10日 - 1

沒問題。但是,我現在需要顯示日期和日期之後的日期以及不同的DateType。

2009年12月31日 - 2
2010年1月1日 - 1
2010年1月2日 - 1
2010年1月3日 - 2
2010年1月9日 - 2
2010年1月10日 - 1
2010年1月11日 - 2

我想我可以用一個工會

SELECT MyDate, DateType 
FROM (
    SELECT mydate - 1 AS MyDate, 2 AS DateType 
    FROM myTable 
    WHERE myTable.fkId = @MyFkId; 

    UNION 

    SELECT mydate + 1 AS MyDate, 2 AS DateType 
    FROM myTable 
    WHERE myTable.fkId = @MyFkId; 

    UNION 

    SELECT mydate AS MyDate, 1 AS DateType 
    FROM myTable 
    WHERE myTable.fkId = @MyFkId; 
) AS myCombinedDateTable 

但是,這包括原始日期的重複項。

2009年12月31日 - 2
2010年1月1日 - 2
2010年1月1日 - 1
2010年1月2日 - 2
2010年1月2日 - 1
2010年1月3日 - 2
2010年1月9日 - 2
2010年1月10日 - 1
2010年1月11日 - 2

如何我最好刪除這些重複項目嗎?我正在考慮臨時表格,但我不確定這是否是最好的方法。

在我看來,它可能會提供性能問題,因爲我在三個不同的時間運行相同的查詢。

什麼是最好的方式來處理這個請求?

+0

它們在技術上並不重複,因爲日期類型不同。哪些日期類型要在重複時顯示? – RedFilter 2010-03-11 17:55:22

+0

@OrbMan,你是對的,如果日期重複,忽略類型2,我想顯示類型1. – 2010-03-11 17:57:32

+0

「2009年1月1日 - 2」來自哪裏(注意1月和2009年)。 – 2010-03-11 17:58:11

回答

1

儘管您已接受的解決方案,讓我給的參考此解決方案:

SELECT MyDate, Min(DateType) 
From 
(
    SELECT MyDate + T1.RecordType AS MyDate, T1.DateType 
    FROM 
    (
    Select 1 AS RecordType, 2 AS DateType 
    Union ALL 
    Select 0 AS RecordType, 1 AS DateType 
    Union ALL 
    Select -1 AS RecordType, 2 AS DateType 
) AS T1 
    CROSS JOIN myTable 
    Where myTable.fkId = @MyFkId 
) AS CombinedTable 
Group By MyDate 

該解決方案的優勢,myTable的查詢只有一次,我們正在對fkID過濾器當前情況所以現在性能並不重要,但如果我們必須評估複雜的查詢,那麼這種技術可以在Union方面正常工作。

+0

這看起來非常好,我現在正在比較效率。儘管如此,我不得不對你的代碼做一些修改。我會更新示例 – 2010-03-11 19:31:49

+0

謝謝,我已經在這裏轉換了答案,因爲性能更好。 IO讀取大約是其他解決方案的1/3,而且CPU一直較少。持續時間非常相似,但您的查詢總是較少。感謝大家的幫助 – 2010-03-11 20:31:16

+0

不客氣,我很高興你能用它....... – 2010-03-12 09:36:08

4

這應該爲你工作:

SELECT MyDate, min(DateType) as DateType 
FROM (
    SELECT mydate - 1 AS MyDate, 2 AS DateType 
    FROM myTable 
    WHERE myTable.fkId = @MyFkId; 

    UNION 

    SELECT mydate + 1 AS MyDate, 2 AS DateType 
    FROM myTable 
    WHERE myTable.fkId = @MyFkId; 

    UNION ALL 

    SELECT mydate AS MyDate, 1 AS DateType 
    FROM myTable 
    WHERE myTable.fkId = @MyFkId; 
) AS myCombinedDateTable 
group by MyDate 

注:我改變了第二UNIONUNION ALL有更好的表現;最後一個子查詢將永遠不會與前兩個子查詢有重複,因爲DateType對於前兩個總是2,對於最後一個UNION ed查詢總是爲1。

+0

道具比我快回來! – CResults 2010-03-11 18:02:58

+0

謝謝!現在我需要看看UNION和UNION ALL。你每天學習新的東西。 – 2010-03-11 18:37:55

+0

對於其他人不知道區別看到這個問題http://stackoverflow.com/questions/49925/what-is-the-difference-between-union-and-union-all – 2010-03-11 18:38:39

0

試過這個,它的工作原理。請注意我使用DATEADD使它與SQL2008的本地SQL副本一起工作。

SELECT MyDate, Min(DateType) 
FROM (
    SELECT DATEADD(DAY,-1,mydate) AS MyDate, 2 AS DateType 
    FROM myTable 
    WHERE myTable.fkId = @MyFkId 

    UNION 

    SELECT DATEADD(DAY,1,mydate) as MyDate, 2 AS DateType 
    FROM myTable 
    WHERE myTable.fkId = @MyFkId 

    UNION 

    SELECT mydate AS MyDate, 1 AS DateType 
    FROM myTable 
    WHERE myTable.fkId = @MyFkId 
) AS myCombinedDateTable 
group by Mydate 
+0

'select getdate() - 1' works在我的SQL Express 2008上很好,你遇到了什麼問題? – RedFilter 2010-03-11 18:04:59

+0

我的不好,我把MyDate定義爲Date而不是DateTime。聲明爲Date並且SQL2008會捕獲一個錯誤。我最近只有使用Date類型的習慣,因爲我討厭處理時間問題! :-) – CResults 2010-03-11 18:09:04

相關問題