我试图通过将两个表连接在一起来创建视图,这绝非困难。但是有一个但是。
我基本上有两张桌子。其中一个存储项目和标签之间的关联,另一个存储父母 - 儿童形式的标签(8个父母,每个孩子有4-6个孩子)。
请允许我说明从我的项目关联表开始:
AssociationId | ItemId | TagId
------------------------------
1 | 2 | 1
2 | 10 | 2
3 | 3 | 1
4 | 5 | 7
...
我的标签表:
TagId | ParentId | Name
------------------------------
1 | NULL | abc sds
2 | 1 | sjdksd as
3 | 1 | djfsd dfs d
4 | NULL | ujkjsd as
...
正如您所见,通过使用ParentId IS NULL
装饰查询可以找到每个父级。
SELECT ITA.AssociationId, ITA.ItemId, ITA.TagId, T.Name as TagName
FROM Item_Tag_Association AS ITA
INNER JOIN Tags AS T
ON T.TagId = ITA.TagId
WHERE T.ParentId IS NULL
如果我要TagId
与ParentId IS NULL
加入两个表格,我会找到所有带有父标记的项目。
如果我要TagId
与ParentId IS NOT NULL
加入两个表格,我会找到所有带有子标记的项目。
但我真正想要的是一个项目和标签列表,其中子标签被父标签取代。
使用上面的例子,结果看起来像这样:
AssociationId | ItemId | TagId | TagName
----------------------------------------
1 | 2 | 1 | abc sds
2 | 10 | 1 | abc sds
3 | 3 | 1 | abc sds
4 | 5 | 7 | ysdasjdhas
...
至于我想要这样做的原因是,我可以计算特定父标记(或该父项的子项)与项目关联的次数。正如你猜到的那样,现在每个孩子都应该为其父母做出贡献。
SELECT DISTINCT ItemId, TagId, TagName, COUNT(ItemId) OVER (PARTITION BY TagId) AS Count
FROM vw_My_View
ORDER BY Count DESC
我正在使用SQL Server 2008 R2。欢迎提出所有建设性意见。
答案 0 :(得分:1)
只要您的父/子层次结构中只有一个级别,您就可以从标签到其自身进行额外的左连接,如果它存在,则可以找到父级:
SELECT ita.AssociationId, ita.ItemId, ISNULL(parent.TagId, t.TagId), ISNULL(parent.Name, t.Name) AS TagName
FROM Item_Tags_Association ita
JOIN Tags t ON ita.TagId = t.TagId
LEFT JOIN Tags parent ON t.ParentId = parent.TagId
第一个(内部)联接可以加入子标记或父标记。如果关联的标记具有父标记,则左连接将包含父标记。 如果不是null,ISNULL将确保使用第二个(左)连接的值,否则使用第一个连接中的值。
如果您不想与ISNULL(或COALESCE)打交道,可以使用UNION和CTE这样的内容:
WITH ParentTags AS (SELECT * FROM Tags WHERE ParentId IS NULL)
SELECT ita.AssociationId, ita.ItemId, t.TagId, t.Name AS TagName
FROM ParentTags t
JOIN Item_Tags_Association ita ON ita.TagId = t.TagId
UNION ALL
SELECT ita.AssociationId, ita.ItemId, t.TagId, t.Name AS TagName
FROM ParentTags t
JOIN Tags child ON t.TagId = child.ParentId
JOIN Item_Tags_Association ita ON ita.TagId = child.TagId