2012-01-15 62 views
1

我有一個存儲星期條目的單個數據庫表。SQL自我加入多次

Id  Value  WeekId 
1   1.0000 1 
2   2.0000 1 

同一周最多可以有三個條目。

所以我想用一個自聯接將解決這個

SELECT w1.Value, w2.Value, w3.Value 
FROM [List].[dbo].[testWeekEntries] as w1 
LEFT OUTER JOIN [List].[dbo].[testWeekEntries] as w2 ON w1.WeekId = w2.weekId 
LEFT OUTER JOIN [List].[dbo].[testWeekEntries] as w3 ON w2.WeekId = w3.WeekId 
WHERE w1.Id < w2.Id AND w2.Id < w3.Id 

的問題:但它不具有一個或兩個條目拉回來一排它worls罰款條目的最大數量。

有沒有不同類型的連接,我可以使用一個或兩個條目或不同的方式來回拉一行?

回答

2

這些條目不會返回,因爲當連接的表返回NULL值時,您的WHERE子句會將其明確地過濾掉。

此解決方案爲每條記錄添加一個順序排列數,每週重新開始爲1。這使您可以在PIVOT語句中使用該序列號

SQL 2000語句

SELECT * 
FROM (
      SELECT (SELECT COUNT(*) 
        FROM testWeekEntries 
        WHERE Id <= we.Id 
          AND WeekId = we.WeekId) as rn 
        , Value 
        , WeekId 
      FROM testWeekEntries we 
     ) q 
PIVOT (MAX(Value) FOR rn IN ([1],[2],[3])) AS PVT 

SQL 2008語句

;WITH q AS (
SELECT rn = ROW_NUMBER() OVER (PARTITION BY WeekId ORDER BY Id) 
     , Id 
     , Value 
     , WeekId 
FROM [testWeekEntries] as w1 
) 
SELECT Value 
     , (SELECT Value FROM q q1 WHERE q1.rn = q.rn + 1 AND q1.WeekId = q.WeekId) 
     , (SELECT Value FROM q q2 WHERE q2.rn = q.rn + 2 AND q2.WeekId = q.WeekId) 
FROM q 
WHERE q.rn = 1 
+0

我想這不過現在帶回了多行,它應該只每週帶回一個行ID – user900566 2012-01-15 12:35:59

+0

@ user900566 - 你是對的, 我的錯。你使用的是什麼DBMS? – 2012-01-15 12:39:03

+0

Ms SQL server 2008 – user900566 2012-01-15 12:42:22

1

您需要將您的WHERE子句中添加w2.Id is nullw3.id is null

因此,像

WHERE 
    (w2.Id is null and w3.id is null) or 
    (w3.id is null and w1.id < w2.id) or 
    (w1.id < w2.id and w2.id < w3.id) 
1

您還可以使用PIVOT

;WITH CTE AS 
(
SELECT Value, 
     WeekId, 
     ROW_NUMBER() OVER (PARTITION BY WeekId ORDER BY Id) AS RN 
FROM [List].[dbo].[testWeekEntries]  
) 
SELECT * 
FROM CTE 
PIVOT (MAX(Value) FOR RN IN ([1],[2],[3])) AS PVT 
+0

+1 Thx Martin,PIVOT仍然不是我的一杯茶,但我必須問:沒有求助於CTE並添加ROW_NUMBER,沒有更簡單的解決方案。 – 2012-01-15 13:23:43

+0

@Lieven - 不是我能想到的! – 2012-01-15 13:33:32

+1

你不知道如何安慰我,。 – 2012-01-15 13:35:24