J'ai une relation de table entre "tag" et "tâche". C'est m: m. La relation est mappée dans la table ' tagtakmapping '.
La table TagAssignment stocke la relation entre une balise et une date. Donc, une balise peut être mappée à une seule date (période).
Je veux émettre une hiérarchie imbriquée de SQL.
Tables SQL :
-- tag assigned to a specific date
CREATE TABLE [dbo].[TagAssignment](
[TagAssignmentID] [int] IDENTITY(1,1) NOT NULL,
[TagID] [int] NOT NULL,
[Period] [date] NOT NULL
);
-- task(s) mapped to tag(s)
CREATE TABLE [dbo].[TagTaskMapping](
[TagID] [int] NOT NULL,
[TaskID] [int] NOT NULL
);
-- tag table
CREATE TABLE [dbo].[Tag](
[TagID] [int] IDENTITY(1,1) NOT NULL,
[TagName] [nvarchar](150) NOT NULL
)
Tableau de mappage TagAssignment Données :
TagAssignmentID TagID Period
24 3 31/05/2017
14 2 31/05/2017
Données de table TagTaskMapping :
TagID TaskID
2 1
2 2
2 3
3 1
3 3
Voici mon Query ...
DECLARE @Period datetime = '2017-05-31'
;WITH CTE_TagAssignment
AS
(
-- GET TAG(S) Assigned to selected PERIOD
SELECT
ta.TagID
,t.TagName
,null as 'Task'
FROM dbo.TagAssignment ta
INNER JOIN
dbo.Tag t
ON t.TagID = ta.TagID
WHERE ta.Period = @Period
UNION ALL
/**USING RECURSION!!!!**/
-- foreach above tag assigned to a period, get it's associated task(s)
SELECT
ttm.TagID
,null AS 'TagName'
,ttm.TaskID as 'Task'
FROM CTE_TagAssignment cta
INNER JOIN
dbo.TagTaskMapping ttm
ON cta.TagID = ttm.TagID
)
SELECT *
FROM CTE_TagAssignment
OPTION (MAXRECURSION 100);
Cependant, je reçois cette erreur: la déclaration terminée. La récursion maximale 100 a été épuisée avant la fin de la déclaration.
C'est la hiérarchie sortie J'aimerais ...
TagID TagName Task
2 Level 5
1
2
3
3 Level 3
1
3
IMHO Vous n'avez pas besoin d'une solution récursive, vous pouvez l'obtenir en utilisant une jointure simple.
DECLARE @Period datetime = '20170531'; SELECT t.TagID, t.TagName, tm.TaskID FROM TagAssignment ta INNER JOIN TagTaskMapping tm ON tm.TagID = ta.TagID INNER JOIN Tag t ON t.TagID = tm.TagID WHERE ta.Period = @period ORDER BY tm.TagID, tm.TaskID; GO
Tagide | TagName | Taskid ----: | : --- -----: [.____] 2 | NIVEAU 5 | 1 [.____] 2 | NIVEAU 5 | 2 [.____] 2 | NIVEAU 5 | 3 [.____] 3 | NIVEAU 3 | 1 3 | NIVEAU 3 | 3
dbfiddle --- (ici
Remarque: Il s'agit essentiellement d'une variation de la solution McNets, avec le formatage que vous avez demandé et une explication du problème avec votre CTE.
Comme les note McNets, vous n'avez pas vraiment de requête récursive. Dans une CTE récursive, la partie récursive de la requête a normalement une certaine condition qui le force à s'arrêter; Il a finalement rencontré un ensemble de valeurs qui ne génèrent aucune ligne de lignes. Le vôtre ahs pas de telles conditions d'arrêt; Il suffit de continuer à générer les nouvelles lignes à plusieurs reprises.
Votre vrai problème est un problème de formatage.
Cela devrait obtenir les résultats que vous souhaitez, dans le format souhaité:
SELECT CASE WHEN Header = 1 THEN CAST(TagID as varchar(20)) ELSE '' END as TagID
,CASE WHEN Header = 1 THEN TagName ELSE '' END as TagName
,CASE WHEN Header = 1 THEN '' ELSE CAST(TaskId as varchar(20)) END as TaskID
FROM (
SELECT DISTINCT
t.TagID, t.TagName, CAST(NULL as int) as TaskID, 1 as Header
FROM TagAssignment ta
INNER JOIN TagTaskMapping tm ON ta.TagID = tm.TagID
INNER JOIN Tag t ON ta.TagID = t.TagID
WHERE ta.Period = @period
UNION ALL
SELECT t.TagID, t.TagName, tm.TaskID, 0 as Header
FROM TagAssignment ta
INNER JOIN TagTaskMapping tm ON ta.TagID = tm.TagID
INNER JOIN Tag t ON ta.TagID = t.TagID
WHERE ta.Period = @period
) sq
ORDER BY sq.TagID, Header DESC, sq.TaskID;
Vérifiez le dbfiddle (à nouveau, sur la base du travail effectué par McNet).