2013-02-09 35 views
2

我有兩個表,其結構類似於此:如何檢索多個明細記錄加上主記錄作爲單行?

人:

ID Name Age 
1 Jack 25 
2 Jill 23 

測試:

ID PersonID TestID Result 
1   1  1  125 
2   1  2  120 
3   1  3  75 
4   2  1  90 
5   2  2  95 
6   2  3  7.2 

有沒有一種方法來檢索的方式一個語句數據主表中的每個記錄都顯示在單行中?事情是這樣的:

PersonID Name Age Test1 Test2 Test3 
     1 Jack 25 125 120  75 
     2 Jill 23  90  95 7.2 

到目前爲止,我想出了一直以創造出遍歷了詳細記錄,並填寫臨時表功能的唯一途徑。不是很優雅。提前

+0

我用這樣的HTTP的功能:// www.itrain.de/knowhow/sql/tsql/pivot/sp_transform_v1_1.asp 但我的尺寸會超大。 – bummi 2013-02-09 09:05:39

回答

2

爲了得到這個結果,您將需要使用PIVOT函數。這將多行中的數據轉換爲列。

如果您事先知道這些值,或者您將擁有有限數量的TestId值,則可以對查詢進行硬編碼以使查詢處於靜態狀態。

SELECT Name, 
    Age, 
    [1] AS Test1, 
    [2] AS Test2, 
    [3] AS Test3 
FROM 
( 
    SELECT P.Name, P.Age, t.TestID, t.Result 
    FROM tests t 
    INNER JOIN person P 
    ON p.ID = t.PersonID 
) T 
PIVOT 
(
    sum(Result) 
    FOR TestID IN ([1], [2], [3]) 
) piv; 

參見SQL Fiddle with Demo

但是,如果您的值有未知數TestId,那麼您將希望使用動態SQL在運行時生成列的列表。您的編碼將爲:

DECLARE @cols AS NVARCHAR(MAX), 
    @colNames AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(testId) 
        from tests 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

select @colNames = STUFF((SELECT distinct ',' + QUOTENAME(testId) +' as Test'+cast(testId as varchar(10)) 
        from tests 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT Name, age, ' + @colnames + ' from 
      (
       select P.Name, P.Age, t.TestID, t.Result 
       from tests t 
       inner join person P 
        on p.ID = t.PersonID 
      ) x 
      pivot 
      (
       sum(Result) 
       for TestID in (' + @cols + ') 
      ) p ' 

execute(@query) 

請參閱SQL Fiddle with Demo

它們都將產生相同的結果,區別在於動態的將增大/減小列,如果測試IDS更改次數:

| NAME | AGE | TEST1 | TEST2 | TEST3 | 
-------------------------------------- 
| Jack | 25 | 125 | 120 | 75 | 
| Jill | 23 | 90 | 95 | 7.2 | 
1

感謝您能在TestID做樞軸

在這裏你去...它有點混亂,但你可以改善它:)

SELECT Name,Age,SUM([1]) AS Test1,SUM([2]) AS Test2,SUM([3]) AS Test3 
FROM(
SELECT P.Name,P.Age,Te.ID, TestID,Result 
FROM Test Te 
INNER JOIN dbo.Person P ON P.ID=Te.PersonID) T 
PIVOT(MAX(T.Result) FOR TestID IN([1],[2],[3])) AS pvt 
GROUP BY Name,Age 

繼承人一些鏈接

http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx http://www.codeproject.com/Questions/393632/How-to-use-Pivot-in-SQL http://blog.sqlauthority.com/2008/06/07/sql-server-pivot-and-unpivot-table-examples/

+0

我迷路了。你能爲我在這裏提供的數據寫一份聲明嗎? – 2013-02-09 09:19:29

+0

我已編輯帖子 – Yugz 2013-02-09 10:13:36

+0

謝謝。事先不知道詳細記錄的數量時,是否可以使用類似的語句? – 2013-02-09 11:21:46