2013-05-29 38 views
1

我需要製作每週視圖計劃日曆。使用sql server在每週視圖日曆中轉換數據

隨着該查詢:

​​

我有一些類似的值:

Num Name DayOfWeek WeekNumber WeekLineNumber 
1 Test1 1   1   1 
2 Test2 1   1   2 
3 Test3 2   1   1 
4 Test4 3   2   1 

編輯我補充這是由ROW_NUMBER()

我會產生WeekLineNumber喜歡把它放在一個像表格(在MS訪問)和日曆我的目標是有這樣的結果

WeekNumber Num1 Name1 Num2 Name2 Num3 Name3 Num4 Name4 (...) 
1   1  Test1 3 Test3 
1   2  Test2 
2          4 Test4 

Num1和Name1用於一週的第一天。第二個是Num2和Name2。 (..)

有2個difficults OMHO:

  • 其中,在每一行中沒有計算數據(我們可以有每週多行)
  • 我不能讓每一個行記錄(這很容易)。我不想爲例子的結果:
 
WeekNumber Num1 Name1 Num2 Name2 Num3 Name3 Num4 Name4 (...) 
1   1  Test1 
1   1    3 Test3 
1   2  Test2 
2          4 Test4 

我需要在第一行的Test1和Test3的。

+1

傳統上,人們會寫一些TSQL .... –

+0

我看你有一個答案。好。 –

回答

2

試試這個 -

模式 -

DECLARE @SQL NVARCHAR(MAX) 

IF OBJECT_ID (N'tempdb.dbo.#temp') IS NOT NULL 
    DROP TABLE #temp 

CREATE TABLE #temp 
(
     Num INT 
    , Name VARCHAR(10) 
    , [DayOfWeek] INT 
    , WeekNumber INT 
    , WeekLineNumber INT 
) 

INSERT INTO #temp (Num, Name, [DayOfWeek], WeekNumber, WeekLineNumber) 
VALUES 
    (1, 'Test1', 1, 1, 1), 
    (2, 'Test2', 1, 1, 2), 
    (3, 'Test3', 2, 1, 1), 
    (4, 'Test4', 3, 2, 1) 

查詢與PIVOT -

DECLARE 
     @sel_cols VARCHAR(MAX) 
    , @cols VARCHAR(MAX) 

SELECT @sel_cols = STUFF((
    SELECT DISTINCT CHAR(13) + ', [Num' + CAST([DayOfWeek] AS VARCHAR(5)) + '] = ISNULL(MAX(CASE WHEN [DayOfWeek] = ' + CAST([DayOfWeek] AS VARCHAR(5)) + ' THEN CAST([Num' + CAST([DayOfWeek] AS VARCHAR(5)) + '] AS CHAR(2)) END), '''')' 
     + CHAR(13) + ', [Name' + CAST([DayOfWeek] AS VARCHAR(5)) + '] = ISNULL(MAX(CASE WHEN [DayOfWeek] = ' + CAST([DayOfWeek] AS VARCHAR(5)) + ' THEN [Name' + CAST([DayOfWeek] AS VARCHAR(5)) + '] END), '''')' 
    FROM #temp 
    FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 2, '') 

PRINT @sel_cols 

SELECT @cols = STUFF((
    SELECT DISTINCT ', [_' + CAST([DayOfWeek] AS VARCHAR(5)) + ']' 
    FROM #temp 
    FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 2, '') 

SELECT @SQL = ' 
SELECT WeekNumber, ' + @sel_cols + ' 
FROM (
    SELECT 
      * 
     , id = ''Name'' + CAST([DayOfWeek] AS VARCHAR(5)) 
     , id2 = ''Num'' + CAST([DayOfWeek] AS VARCHAR(5)) 
    FROM #temp t 
) t3 
PIVOT (
    MAX(Name) 
    FOR id IN (' + REPLACE(@cols, '_', 'Name') + ') 
) pivot1 
PIVOT (
    MAX(Num) 
    FOR id2 IN (' + REPLACE(@cols, '_', 'Num') + ') 
) pivot2 
GROUP BY WeekNumber, WeekLineNumber 
ORDER BY WeekNumber 
' 

EXEC sys.sp_executesql @SQL 

查詢與枚舉 -

DECLARE 
     @WeekStart INT 
    , @WeekEnd INT 

SELECT 
     @WeekStart = 1 
    , @WeekEnd = 7 

SELECT @SQL = STUFF((
    SELECT CHAR(13) + ', [Num' + num + '] = ISNULL(MAX(CASE WHEN [DayOfWeek] = ' + num + ' THEN CAST([Num] AS CHAR(2)) END), '''')' 
     + CHAR(13) + ', [Name' + num + '] = ISNULL(MAX(CASE WHEN [DayOfWeek] = ' + num + ' THEN [Name] END), '''')' 
    FROM (
     SELECT num = CAST(sv.number AS CHAR(1)) 
     FROM [master].dbo.spt_values sv 
     WHERE sv.[type] = 'p' 
      AND sv.number BETWEEN @WeekStart AND @WeekEnd 
    ) sv 
    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, 'SELECT 
    [WeekNumber] 
,') + ' FROM #temp 
GROUP BY WeekNumber, WeekLineNumber 
ORDER BY WeekNumber' 

EXEC sys.sp_executesql @SQL 

輸出 -

1。PIVOT

WeekNumber Num1 Name1  Num2 Name2  Num3 Name3 
----------- ---- ---------- ---- ---------- ---- ---------- 
1   1 Test1  3 Test3   
1   2 Test2       
2           4 Test4   

2.枚舉

WeekNumber Num1 Name1  Num2 Name2  Num3 Name3  Num4 Name4  Num5 Name5  Num6 Name6  Num7 Name7 
----------- ---- ---------- ---- ---------- ---- ---------- ---- ---------- ---- ---------- ---- ---------- ---- ---------- 
1   1 Test1  3 Test3                   
1   2 Test2                       
2           4 Test4               
+0

我不害怕。我想在第一行上填寫Name1和Name2,否則我無法在ms訪問中顯示它。 (將會出現空行)PS:我購買了您的架構比較devart;) –

+0

例如,您可以爲一週中的所有天或周的一部分生成查詢。 – Devart

+0

請參閱最新的答案。 – Devart

1

使用您所提供的數據集並將其加載到一個臨時表#TEST,下面是給出結果所需格式的查詢:

SELECT [WeekNumber] 
     ,CASE WHEN [DayOfWeek]=1 THEN 1  ELSE NULL END AS [Num1] 
     ,Case WHEN [DayOfWeek]=1 THEN [Name] ELSE NULL END AS [Name1] 
     ,CASE WHEN [DayOfWeek]=2 THEN 2  ELSE NULL END AS [Num2] 
     ,Case WHEN [DayOfWeek]=2 THEN [Name] ELSE NULL END AS [Name2] 
     ,CASE WHEN [DayOfWeek]=3 THEN 3  ELSE NULL END AS [Num3] 
     ,Case WHEN [DayOfWeek]=3 THEN [Name] ELSE NULL END AS [Name3] 
     ,CASE WHEN [DayOfWeek]=4 THEN 4  ELSE NULL END AS [Num4] 
     ,Case WHEN [DayOfWeek]=4 THEN [Name] ELSE NULL END AS [Name4] 
     ,CASE WHEN [DayOfWeek]=5 THEN 5  ELSE NULL END AS [Num5] 
     ,Case WHEN [DayOfWeek]=5 THEN [Name] ELSE NULL END AS [Name5] 
     ,CASE WHEN [DayOfWeek]=6 THEN 6  ELSE NULL END AS [Num6] 
     ,Case WHEN [DayOfWeek]=6 THEN [Name] ELSE NULL END AS [Name6] 
     ,CASE WHEN [DayOfWeek]=7 THEN 7  ELSE NULL END AS [Num7] 
     ,Case WHEN [DayOfWeek]=7 THEN [Name] ELSE NULL END AS [Name7] 
from #Test 

如果您不希望看到的NULL然後使用下面的代碼:空值REPL;進洞與BLANKS:

Select [WeekNumber] 
     ,CASE WHEN [DayOfWeek]=1 THEN cast(1 as Char(2))  ELSE '' END AS [Num1] 
     ,Case WHEN [DayOfWeek]=1 THEN [Name] ELSE '' END AS [Name1] 
     ,CASE WHEN [DayOfWeek]=2 THEN cast(2 as Char(2))   ELSE '' END AS [Num2] 
     ,Case WHEN [DayOfWeek]=2 THEN [Name] ELSE '' END AS [Name2] 
     ,CASE WHEN [DayOfWeek]=3 THEN cast(3 as Char(2))   ELSE '' END AS [Num3] 
     ,Case WHEN [DayOfWeek]=3 THEN [Name] ELSE '' END AS [Name3] 
     ,CASE WHEN [DayOfWeek]=4 THEN cast(4 as Char(2))   ELSE '' END AS [Num4] 
     ,Case WHEN [DayOfWeek]=4 THEN [Name] ELSE '' END AS [Name4] 
     ,CASE WHEN [DayOfWeek]=5 THEN cast(5 as Char(2))   ELSE '' END AS [Num5] 
     ,Case WHEN [DayOfWeek]=5 THEN [Name] ELSE '' END AS [Name5] 
     ,CASE WHEN [DayOfWeek]=6 THEN cast(6 as Char(2))   ELSE '' END AS [Num6] 
     ,Case WHEN [DayOfWeek]=6 THEN [Name] ELSE '' END AS [Name6] 
     ,CASE WHEN [DayOfWeek]=7 THEN cast(7 as Char(2))   ELSE '' END AS [Num7] 
     ,Case WHEN [DayOfWeek]=7 THEN [Name] ELSE '' END AS [Name7] 
from #Test 

OUTPUT:

WeekNumber Num1 Name1 Num2 Name2 Num3 Name3 Num4 Name4 Num5 Name5 Num6 Name6 Num7 Name7 
----------- ---- ----- ---- ----- ---- ----- ---- ----- ---- ----- ---- ----- ---- ----- 
1   1 Test2                
1      2 Test3             
2         3 Test4          
1   1 Test1                

(4 row(s) affected) 
+0

這是不可能的,我擔心。請看我給出的最後一個例子。在第一週的第一行,我會在Num2和Name2列的第一行有NULL值,這不是很好的行爲。 –

+0

我在上面的答案中添加了代碼,其中的NULL被刪除,並且得到與您的問題中指定的結果相同的結果。 –

+0

以及我認爲有一個誤解,可能是我的錯,問題的最後結果是我不想要的結果。我希望在第一行有Test1和Test3(請參閱WeekLineNumber) –

1

我想我找到了解決辦法。首先,創建表(感謝devart)

 
IF OBJECT_ID (N'tempdb.dbo.#temp') IS NOT NULL 
    DROP TABLE #temp 

CREATE TABLE #temp 
(
     Num INT 
    , Name VARCHAR(10) 
    , [DayOfWeek] INT 
    , WeekNumber INT 
    , WeekLineNumber INT 
) 

INSERT INTO #temp (Num, Name, [DayOfWeek], WeekNumber, WeekLineNumber) 
VALUES 
    (1, 'Test1', 1, 1, 1) 

INSERT INTO #temp (Num, Name, [DayOfWeek], WeekNumber, WeekLineNumber) 
VALUES 
    (2, 'Test2', 1, 1, 2) 

INSERT INTO #temp (Num, Name, [DayOfWeek], WeekNumber, WeekLineNumber) 
VALUES 
    (3, 'Test3', 2, 1, 1) 

INSERT INTO #temp (Num, Name, [DayOfWeek], WeekNumber, WeekLineNumber) 
VALUES 
    (4, 'Test4', 3, 2, 1) 

,然後查詢它:

 
SELECT 
     WeekNumber 
     ,WeekLineNumber 
    , MAX(CASE WHEN DayOfWeek = 1 THEN [Num] ELSE NULL END) AS Num1 
    , MAX(CASE WHEN DayOfWeek = 1 THEN [Name] ELSE NULL END) AS Name1 
    , MAX(CASE WHEN DayOfWeek = 2 THEN [Num] ELSE NULL END) AS Num2 
    , MAX(CASE WHEN DayOfWeek = 2 THEN [Name] ELSE NULL END) AS Name2 
    , MAX(CASE WHEN DayOfWeek = 3 THEN [Num] ELSE NULL END) AS Num3 
    , MAX(CASE WHEN DayOfWeek = 3 THEN [Name] ELSE NULL END) AS Name3 
    , MAX(CASE WHEN DayOfWeek = 4 THEN [Num] ELSE NULL END) AS Num4 
    , MAX(CASE WHEN DayOfWeek = 4 THEN [Name] ELSE NULL END) AS Name4 
    , MAX(CASE WHEN DayOfWeek = 5 THEN [Num] ELSE NULL END) AS Num5 
    , MAX(CASE WHEN DayOfWeek = 5 THEN [Name] ELSE NULL END) AS Name5 
    , MAX(CASE WHEN DayOfWeek = 6 THEN [Num] ELSE NULL END) AS Num6 
    , MAX(CASE WHEN DayOfWeek = 6 THEN [Name] ELSE NULL END) AS Name6 
    , MAX(CASE WHEN DayOfWeek = 7 THEN [Num] ELSE NULL END) AS Num7 
    , MAX(CASE WHEN DayOfWeek = 7 THEN [Name] ELSE NULL END) AS Name7 
    FROM #temp 
GROUP BY WeekNumber, WeekLineNumber

導致:

 
WeekNumber WeekLineNumber Num1 Name1 Num2 Name2 Num3 Name3 Num4 Name4 Num5 Name5 Num6 Name6 Num7 Name7 
1   1    1  Test1 3 Test3 
1   2    2  Test2 
2   1           4 Test4 

+0

我試過你的例子,但無法得到結果你在'哪個結果'中指定了什麼。問題可能在於輸入數據嗎?請查看示例數據。 – Devart

+1

你是完全正確的。當我寫回堆棧溢出代碼時,我犯了一個錯誤。我糾正它,並感謝你。 –

0

你正在嘗試做無異於一場交叉表或關鍵點。

如果您可以導入或鏈接到原始表格(非交叉表格)的數據,則可以在Access中進行交叉製表。查看訪問交叉製表查詢和相應的查詢嚮導。

+0

我想我可以使用交叉表,但結果不會是我需要的。我的最終目標是創建一個可打印的報告以及一個支持交互的窗體,比如點擊以獲得一些細節。 –

+0

您可以在交叉查詢的頂部放置報告。我不確定一個表格。 –