2017-09-05 57 views
2

鑑於表TSQL樞軸旋轉可變長度的子查詢

Country 
ID Name 
1  USA 
2  Canada 
3  Australia 

Territory 
ID CountryID  Name 
1  1    Michigan 
2  1    Colorado 
3  1    Iowa 
4  2    Manitoba 
5  2    Quebec 
6  2    Saskatchewan 
7  2    Alberta 
8  3    Queensland 
9  3    Victoria 

SubDivisions 
ID  TerritoryID Name 
1  8    Stanley 
2  8    Ward 
3  8    Canning 
4  9    Bourke 
5  9    Dalhousie 
6  9    Grant 
7  1    Washtenaw 
8  1    Alpena 
9  2    Baca 
10  2    Delta 
11  2    Doug 
12  3    Adams 
13  3    Fayette 
14  3    Decatur 
15  3    Hancock 
16  4    Eastman 
17  4    Interlake 
18  5    Estrie 
19  5    Montreal 
20  5    Cote-Nord 
21  5    Bas-Saint-Laurent 
22  6    Kootenays 
23  6    Okanagan 
24  6    Thompson 
25  7    Athabasca 
26  7    MacKenzie 
27  7    Saddle Hills 

我一直沒能創建使用支點的查詢會產生這樣的輸出(國家,地區):

Australia Queensland Canning   Stanley Ward 
Australia Victoria  Bourke    Dalhousie Grant 
Canada  Alberta  Athabasca   MacKenzie Saddle Hills 
Canada  Manitoba  Eastman   Interlake 
Canada  Quebec  Bas-Saint-Laurent Cote-Nord Estrie  Montreal 
Canada  Saskatchewan Kootenays   Okanagan Thompson 
USA   Colorado  Baca    Delta  Doug 
USA   Iowa   Adams    Decatur Fayette  Hancock 
USA   Michigan  Alpena    Washtenaw` 

讓所有東西都是有序的,而不是嚴格要求。我知道我怎麼可以用光標來做,但剛剛學會了Pivot,我正在跳躍尋找更好的方法。另外,Pivot似乎需要某種聚合函數,我不需要這個值,但在結果集中它很容易被忽略。

TIA

此外,爲了方便下面的SQL腳本將創建和填寫測試表中我描述:

Create Table Country 
    (ID int, Name VarChar(50)) 
Go 

Insert Country (ID,Name) 
Values (1,'USA') 
Insert Country (ID,Name) 
Values (2,'Canada') 
Insert Country (ID,Name) 
Values (3,'Australia') 
Go 

Create Table Territory 
    (ID int, CountryID int, Name VarChar(50)) 
Go 

Insert Territory (ID,CountryID,Name) 
Values (1,1,'Michigan') 
Insert Territory (ID,CountryID,Name) 
Values (2,1,'Colorado') 
Insert Territory (ID,CountryID,Name) 
Values (3,1,'Iowa') 
Insert Territory (ID,CountryID,Name) 
Values (4,2,'Manitoba') 
Insert Territory (ID,CountryID,Name) 
Values (5,2,'Quebec') 
Insert Territory (ID,CountryID,Name) 
Values (6,2,'Saskatchewan') 
Insert Territory (ID,CountryID,Name) 
Values (7,2,'Alberta') 
Insert Territory (ID,CountryID,Name) 
Values (8,3,'Queensland') 
Insert Territory (ID,CountryID,Name) 
Values (9,3,'Victoria') 
Go 

Create Table SubDivisions 
    (ID int, TerritoryID int, Name VarChar(50)) 
Go 

Insert SubDivisions (ID, TerritoryID, Name) 
Values (1, 8, 'Stanley') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (2, 8, 'Ward') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (3, 8, 'Canning') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (4, 9, 'Bourke') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (5, 9, 'Dalhousie') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (6, 9, 'Grant') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (7, 1, 'Washtenaw') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (8, 1, 'Alpena') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (9, 2, 'Baca') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (10, 2, 'Delta') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (11, 2, 'Doug') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (12, 3, 'Adams') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (13, 3, 'Fayette') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (14, 3, 'Decatur') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (15, 3, 'Hancock') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (16, 4, 'Eastman') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (17, 4, 'Interlake') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (18, 5, 'Estrie') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (19, 5, 'Montreal') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (20, 5, 'Cote-Nord') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (21, 5, 'Bas-Saint-Laurent') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (22, 6, 'Kootenays') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (23, 6, 'Okanagan') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (24, 6, 'Thompson') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (25, 7, 'Athabasca') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (26, 7, 'MacKenzie') 
Insert SubDivisions (ID, TerritoryID, Name) 
Values (27, 7, 'Saddle Hills') 
Go 
+0

這些列名是什麼?或者,逗號分隔的字符串值是否足夠? – scsimon

+0

列名也是一種魅力,所以它們是可選的。查詢的結果是供個人使用的。 – Nottoc

回答

0

試試這個SQL(需要SQL Server 2012+)

select 
    t.CountryName 
    ,t.TerritoryName 
    ,Col1 = max(Col1) 
    ,Col2 = max(Col2) 
    ,Col3 = max(Col3) 
    ,Col4 = max(Col4) 
    ,Col5 = max(Col5) 
    ,Col6 = max(Col6) 
    ,Col7 = max(Col7) 
    ,Col8 = max(Col8) 
from (
    select 
     CountryName  = Country.Name 
     ,TerritoryName  = Territory.Name 
     ,SubDivisionsName = SubDivisions.Name 
     ,ColNo = row_number() over (partition by Country.Name,Territory.Name 
            order by SubDivisions.Name) 
    from Country 
    join Territory  on Territory.CountryID  = Country.ID 
    join SubDivisions on SubDivisions.TerritoryID = Territory.ID 
) data 
cross apply (values 
    (CountryName, TerritoryName, 1, SubDivisionsName, '', '', '', '', '', '', '') 
    ,(CountryName, TerritoryName, 2, '', SubDivisionsName, '', '', '', '', '', '') 
    ,(CountryName, TerritoryName, 3, '', '', SubDivisionsName, '', '', '', '', '') 
    ,(CountryName, TerritoryName, 4, '', '', '', SubDivisionsName, '', '', '', '') 
    ,(CountryName, TerritoryName, 5, '', '', '', '', SubDivisionsName, '', '', '') 
    ,(CountryName, TerritoryName, 6, '', '', '', '', '', SubDivisionsName, '', '') 
    ,(CountryName, TerritoryName, 7, '', '', '', '', '', '', SubDivisionsName, '') 
    ,(CountryName, TerritoryName, 8, '', '', '', '', '', '', '', SubDivisionsName) 
) t(CountryName, TerritoryName, ColNo, Col1, Col2, Col3, Col4, Col5, Col6, Col7, Col8) 
where t.CountryName  = data.CountryName 
    and t.TerritoryName = data.TerritoryName 
    and t.ColNo = data.ColNo 
group by 
    t.CountryName 
    ,t.TerritoryName 
order by 
    t.CountryName 
    ,t.TerritoryName 

這將產生所需的輸出:

enter image description here

注意特別是在cross apply使用valuesclause的還有交叉應用本身。 交叉適用也進入類似於外部加入的風味;稱爲適當的外部適用

+0

似乎這個樞紐是爲了實現除了我想實現的目的之外的目的而發明的。謝謝你的時間。 – Nottoc

+0

@Nottoc:樞軸是一個窮人的交叉應用。 ;-)因爲我發現了交叉應用,所以我從不使用pivot。 –