There are five or more database tables, that are related to each other like in the following database schema:
Here is the code for creating them:
-- Table 1
CREATE TABLE [dbo].[Table1](
[Id] [INT] NOT NULL,
[Title] [NCHAR](10) NOT NULL,
[Annotation] [NCHAR](10) NOT NULL,
CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
-- Table 2 referencing Table 1
CREATE TABLE [dbo].[Table2](
[Id] [INT] NOT NULL,
[Table1_Id] [INT] NOT NULL,
[Title] [NCHAR](10) NOT NULL,
CONSTRAINT [PK_Table2] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Table2] WITH CHECK ADD CONSTRAINT [FK_Table2_Table1] FOREIGN KEY([Table1_Id])
REFERENCES [dbo].[Table1] ([Id])
GO
ALTER TABLE [dbo].[Table2] CHECK CONSTRAINT [FK_Table2_Table1]
GO
-- Table 2_1 referencing Table 2
CREATE TABLE [dbo].[Table2_1](
[Id] [INT] NOT NULL,
[Table2_Id] [INT] NOT NULL,
[Title] [NCHAR](10) NOT NULL,
CONSTRAINT [PK_Table2_1] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Table2_1] WITH CHECK ADD CONSTRAINT [FK_Table2_1_Table2] FOREIGN KEY([Table2_Id])
REFERENCES [dbo].[Table2] ([Id])
GO
ALTER TABLE [dbo].[Table2_1] CHECK CONSTRAINT [FK_Table2_1_Table2]
GO
-- Table 3 referencing Table 1
CREATE TABLE [dbo].[Table3](
[Id] [INT] NOT NULL,
[Table1_Id] [INT] NOT NULL,
[Title] [NCHAR](10) NOT NULL,
CONSTRAINT [PK_Table3] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Table3] WITH CHECK ADD CONSTRAINT [FK_Table3_Table1] FOREIGN KEY([Table1_Id])
REFERENCES [dbo].[Table1] ([Id])
GO
ALTER TABLE [dbo].[Table3] CHECK CONSTRAINT [FK_Table3_Table1]
GO
-- Table 3_1 referencing Table 3
CREATE TABLE [dbo].[Table3_1](
[Id] [INT] NOT NULL,
[Table3_Id] [INT] NOT NULL,
[Title] [NCHAR](10) NOT NULL,
CONSTRAINT [PK_Table3_1] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Table3_1] WITH CHECK ADD CONSTRAINT [FK_Table3_1_Table3] FOREIGN KEY([Table3_Id])
REFERENCES [dbo].[Table3] ([Id])
GO
ALTER TABLE [dbo].[Table3_1] CHECK CONSTRAINT [FK_Table3_1_Table3]
GO
Now I add the following record samples to the table:
INSERT INTO table1 VALUES (1, 'FirstTitle', 'FirstAnno')
INSERT INTO table2 VALUES (1, 1, 'Tab2Title')
INSERT INTO table3 VALUES (1, 1, 'Tab3Title')
INSERT INTO table2_1 VALUES (1, 1, 'Tab21Sub')
INSERT INTO table3_1 VALUES (1, 1, 'Tab31Sub')
Querying this tables with a JOIN FOR XML like
SELECT * FROM Table1 AS T1
JOIN Table2 AS T2 ON T1.Id = T2.Table1_Id
JOIN Table3 AS T3 ON T1.Id = T3.Table1_Id
JOIN Table2_1 AS T21 ON T2.Id = T21.Table2_Id
JOIN Table3_1 AS T31 ON T3.Id = T31.Table2_Id
FOR XML AUTO
will end in this result
<T1 Id="1" Title="FirstTitle" Annotation="FirstAnno ">
<T2 Id="1" Table1_Id="1" Title="Tab2Title ">
<T3 Id="1" Table1_Id="1" Title="Tab3Title ">
<T21 Id="1" Table2_Id="1" Title="Tab21Sub ">
<T31 Id="1" Table3_Id="1" Title="Tab31Sub " />
</T21>
</T3>
</T2>
</T1>
while I'm expecting this
<T1 Id="1" Title="FirstTitle" Annotation="FirstAnno ">
<T2 Id="1" Table1_Id="1" Title="Tab2Title ">
<T21 Id="1" Table2_Id="1" Title="Tab21Sub" />
</T2>
<T3 Id="1" Table1_Id="1" Title="Tab3Title ">
<T31 Id="1" Table3_Id="1" Title="Tab31Sub" />
</T3>
</T1>
So how can I modify the query, perhaps making subqueries to get the expected result, sorting Table 3 at the same level and not beneath table2, and also sorting the childs of table2_1 and table3_1 beneath there parents?
Given your hierarchical example I've fleshed out the example data to include some more subitems...
If you use
FOR XML AUTO
and correlated subqueries that returnFOR XML AUTO, TYPE
such as the following:You can return nested XML data such as the following: