2012-08-30 63 views
0

現在我有這樣的比賽彙總表:SQL如何從彙總表創建細節表

Summay Table

而且我想通過時間分割的「開始時間」和「結束時間」,並把它轉換成以下詳細請看:

I need this

這是因爲逆透視一種類似,但並不完全相同。我應該如何編寫sql語句?謝謝!

+2

[你嘗試過什麼?](HTTP:// whathaveyoutried.com)如果你發佈你試過的東西,人們往往會更傾向於提供幫助。我們不希望爲他們做人的工作,但是如果你嘗試過的SQL中有某些東西存在,你會被困住,我們會提供幫助。 –

+2

你使用的是什麼RDBMS和版本? – Lamak

+0

我正在使用SQL Server 2008,thx! – Echo

回答

3

在PostgreSQL是:

SELECT PlayerID 
    , generate_series(s.StartTime, s.EndTime - 1) AS StartTimeCol 
    , generate_series(s.StartTime + 1, s.EndTime) AS EndTimeCol 
FROM summaryTable s 

在此Link,你可以看到如何generate_series功能添加到SQL Server 2008中

查看在行動Here

1

如果你在SQL Server上,你可以嘗試下面的TSQL塊。它使用遊標來遍歷開始和結束時間之間的時間超過1小時的那些行,並迭代遍歷,將單個「小時」添加到@gamesTable表變量中。

一旦光標完成並已將記錄填充到@gamesTable變量中,那麼對於在開始和結束時間之間具有1個或更少小時的那些行的原始表,SELECT語句將與存儲到的所有行@gamesTable。

DECLARE Game_Cursor CURSOR FOR 
    SELECT * 
    FROM summaryTable 
    WHERE EndTime - StartTime > 1 

OPEN Game_Cursor; 
DECLARE @PlayerID char 
DECLARE @StartTime int 
DECLARE @EndTime int 
DECLARE @TempEndTime int 
DECLARE @gamesTable TABLE(PlayerID char, StartTime int, EndTime int) 

--Fetch the first row 
FETCH NEXT FROM Game_Cursor INTO @PlayerID, @StartTime, @EndTime 
WHILE @@FETCH_STATUS = 0 
BEGIN 
     WHILE (@EndTime - @StartTime) > 0 
     BEGIN 
      SET @TempEndTime = @StartTime + 1 
      INSERT INTO @gamesTable 
       SELECT @PlayerID AS PlayerID, @StartTime AS StartTime, @TempEndTime AS EndTime 

      SET @StartTime = @StartTime + 1 
     END; 

     --Fetch the next row 
     FETCH NEXT FROM Game_Cursor INTO @PlayerID, @StartTime, @EndTime 
END; 

--Rid of the cursor 
CLOSE Game_Cursor; 
DEALLOCATE Game_Cursor; 

--Output the results 
SELECT * FROM summaryTable WHERE (EndTime - StartTime) <= 1 
UNION ALL 
SELECT * FROM @gamesTable 
+0

[爲什麼人們討厭SQL遊標這麼多?](http://stackoverflow.com/questions/287445/why-do- people-hate-sql-cursors-so-much) – Kermit

+0

我認爲有些人不喜歡遊標,因爲他們有時被用在他們不是最有效的解決方案和浪費資源的情況下。 –

1

在SQL Server 2005 +,你可以使用CTE得到的結果:

;with cte (playerid, starttime, endtime) as 
(
    select playerid, min(starttime) starttime, max(endtime) endtime 
    from yourtable 
    group by playerid 
    union all 
    select playerid, starttime + 1, endtime 
    from cte 
    where starttime < endtime 
) 
select playerid, 
    starttime, 
    case 
    when starttime + 1 < endtime 
    then starttime + 1 
    else endtime 
    end endtime 
from cte 
where starttime != endtime 
order by playerid, starttime 

SQL Fiddle with Demo