2016-03-24 102 views
2

嵌套XML文件我有3个表,我需要参加3个表格,以创建一个嵌套的XML文件创建SQL Server中

的表是活动,UserEvents和用户。下面是一个例子模式:(!还是东西沿着这些线路)

create table [dbo].[Users] 
(
    UserID int, 
    Username VARCHAR(MAX) 
); 


insert into [dbo].[Users] (UserID, Username) values 
(155, 'jweldz'), 
(218, 'pwarner'), 
(310, 'jeffrey') 


create table dbo.Events 
(
    [Id] [int] IDENTITY(1,1) NOT NULL, 
    [UserId] [int] NULL, 
    [Title] [nvarchar](250) NOT NULL, 
    [EventStart] [datetime] NOT NULL, 
); 

SET IDENTITY_INSERT [Events] ON 
INSERT INTO [dbo].[Events] ([Id], [UserId], [Title], [EventStart]) 
VALUES (3409, NULL, 'Boxing Match', '2014-10-05 00:00:00.000') 


create table dbo.UserEvents 
(
    UserID int, 
    EventID int, 
); 



INSERT INTO [dbo].[UserEvents] ([UserID], [EventID]) VALUES (155, 3409), (218, 3409), (310, 3409) 

SQL Fiddle

使用这种模式,我想创建以下格式的嵌套的XML输出在SQL Server 2014的每个用户在事件被列于一个事件标签:

<EventList> 
    <Event eventid="3409"> 
    <Title>Boxing Match</Title> 
    <Player> 
     <UserID>155</UserID> 
     <Username>jweldz</Username> 
     <UserID>218</UserID> 
     <Username>pwarner</Username> 
     <UserID>310</UserID> 
     <Username>jeffrey</Username> 
    </Player> 
    <EventStart>2016-04-16T09:00:00</EventStart> 
    </Event> 
</EventList> 

而是我得到:

<EventList> 
     <Event eventid="3409"> 
     <Title>Boxing Match</Title> 
     <Player> 
      <UserID>155</UserID> 
      <Username>jweldz</Username> 
     </Player> 
     <EventStart>2016-04-16T09:00:00</EventStart> 
     </Event> 
     <Event eventid="3409"> 
     <Title>Boxing Match</Title> 
     <Player> 
      <UserID>218</UserID> 
      <Username>pwarner</Username> 
     </Player> 
     <EventStart>2016-04-16T09:00:00</EventStart> 
     </Event> 
</EventList> 
.... 

每次有新玩家都会重复该事件,但这并不理想。如何使用SQL Server 2014将播放器嵌套到一个事件标签中?

+0

大问题!示例代码,小提琴,预期输出,实际输出。 +1从我身边 – Shnugo

回答

2

此查询应该提供您所需要的:

SELECT e.Id AS [@eventid] 
     ,e.Title 
     ,(
     SELECT u.UserID 
       ,u.Username 
     FROM dbo.Users AS u 
     INNER JOIN dbo.UserEvents AS ue ON u.UserID=ue.UserID 
     WHERE e.Id=ue.EventID 
     FOR XML PATH(''),TYPE 
    ) AS Player 
     ,e.EventStart 
FROM dbo.Events AS e 
FOR XML PATH('Event'),ROOT('EventList') 

结果

<EventList> 
    <Event eventid="3409"> 
    <Title>Boxing Match</Title> 
    <Player> 
     <UserID>155</UserID> 
     <Username>jweldz</Username> 
     <UserID>218</UserID> 
     <Username>pwarner</Username> 
     <UserID>310</UserID> 
     <Username>jeffrey</Username> 
    </Player> 
    <EventStart>2014-05-10T00:00:00</EventStart> 
    </Event> 
</EventList> 

但会强烈建议你保持你的用户分开!有了这个:

SELECT e.Id AS [@eventid] 
     ,e.Title 
     ,(
     SELECT u.UserID AS [@userid] 
       ,u.Username AS [@username] 
     FROM dbo.Users AS u 
     INNER JOIN dbo.UserEvents AS ue ON u.UserID=ue.UserID 
     WHERE e.Id=ue.EventID 
     FOR XML PATH('User'),TYPE 
    ) AS Player 
     ,e.EventStart 
FROM dbo.Events AS e 
FOR XML PATH('Event'),ROOT('EventList') 

...你会得到这个

<EventList> 
    <Event eventid="3409"> 
    <Title>Boxing Match</Title> 
    <Player> 
     <User userid="155" username="jweldz" /> 
     <User userid="218" username="pwarner" /> 
     <User userid="310" username="jeffrey" /> 
    </Player> 
    <EventStart>2014-05-10T00:00:00</EventStart> 
    </Event> 
</EventList> 
+0

完美,谢谢!我在错误的地方加入了JOIN。 +1 – Powellellogram

+0

@Powellellogram我编辑了我的答案。如果你不分离你的用户,那么把userID和userName放在一起就更加不合适了! – Shnugo

+0

谢谢,很高兴接受好的建议。我会用你的第二个例子! – Powellellogram