2017-09-05 8 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` 

注文されたものすべてが魅力的であり、厳密に要求されるものではありません。私はカーソルを使ってどのように行うことができるのか知っていますが、ちょうどピボットを学んだだけで、より良い方法で飛び降りていました。また、Pivo​​tはある種の集計関数を必要としているようですが、その値は必要ありませんが、結果セットでは簡単に無視されます。

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

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 
(2012+ SQL Serverが必要)このSQLを試してみてください

は、所望の出力を生成する:

enter image description here

注特にcross applyvaluesclauseの使用ならびにクロス自体が適用されます。 クロス・アプライには、外部結合に似たフレーバーが付属しています。適切にと呼ばれ、外側はに適用されます。

+0

ピボットは私が達成しようとしていた以外の目的を達成するために発明されたようです。御時間ありがとうございます。 – Nottoc

+0

@Nottoc:ピボットは、貧しい人のクロスが適用されます。 ;-)私は交差適用を発見して以来、ピボットを使用していません。 –

関連する問題