我想在族树中显示数据。我可以很容易地使用下面的查询。我在城市的条件面临问题。如果我搜索city是 paris ,那么它将仅显示属于 paris 的那些数据,但我想显示那些家族头属于 paris <的数据/ em>的。 (如果家庭主人属于 paris 那么显示所有孩子的家长。不需要孩子来自巴黎)。 -1是根级头
; WITH CTE
AS (
SELECT ROW_NUMBER() OVER (ORDER BY c.ContactId) as MCID , 1 as CID
,c.contactId
FROM ContactDetail c where c.FamilyHeadId = -1
UNION ALL
SELECT cte.MCID as MCID ,
CONVERT(INT,(
CONVERT(VARCHAR(10),CTE.CID) +
CONVERT(VARCHAR(10),ROW_NUMBER() OVER (ORDER BY p.ContactId))
)
) AS CID
,p.contactId
FROM ContactDetail p INNER JOIN cte ON p.FamilyHeadId = CTE.ContactId
)
select * from CTE
inner join ContactDetail b on cte.contactid = b.contactid
order by mcid,CID
答案 0 :(得分:2)
您可以移动过滤器&#34; Paris&#34;进入CTE的初始锚定查询(即家庭负责人的搜索也将受到城市的限制)。但是,在CTE中UNION
之后的递归查询中不得重复此谓词(因为不需要约束子项)。我在CityName
上假设了一列ContactDetail
,但可能您的实际模型与City表格之间存在规范化关系:
; WITH CTE
AS (
SELECT ROW_NUMBER() OVER (ORDER BY c.ContactId) as MCID, 1 as CID, c.contactId
FROM ContactDetail c
WHERE c.FamilyHeadId = -1 AND c.City = 'Paris'
UNION ALL
SELECT cte.MCID as MCID,
CONVERT(INT, (CONVERT(VARCHAR(10),CTE.CID) +
CONVERT(VARCHAR(10),ROW_NUMBER() OVER (ORDER BY p.ContactId)))) AS CID
,p.contactId
FROM ContactDetail p
INNER JOIN cte ON p.FamilyHeadId = CTE.ContactId
)
SELECT * FROM CTE
INNER JOIN ContactDetail b on cte.contactid = b.contactid
order by mcid, CID;
请注意,您还可以通过根据updated SqlFiddle
从2个CTE查询中发出所有必填字段,避免外部查询中的最终连接返回到同一个表。答案 1 :(得分:0)
实际上变量表可能比光标更好,所以我利用plz检查这个查询它应该帮助你。
declare @allheadCount int, @allheadCounttree int , @contactId int
declare @city varchar(50), @name varchar(50)
set @allheadCounttree =0
DECLARE @familyTree TABLE
(
familyId int IDENTITY(1,1),
contactId int ,
familyHeadId int,
Name varchar(50) NOT NULL,
city varchar(50) NOT NULL,
headcity varchar(50) NOT NULL
)
select @allheadCount = count(contactid) from contactdetail where familyheadid = -1
WHILE @allheadCount <> @allheadCounttree
BEGIN
select top 1 @contactid = contactId, @name=name, @city=city from contactdetail where familyheadid = -1 and contactid not in (select distinct contactid from @familytree )
insert into @familyTree (contactid,familyheadid,name,city,headcity) Values (@contactId,-1,@name,@city,@city)
insert into @familyTree (contactid,familyheadid,name,city,headcity)
select contactid,@contactId,name,city,@city from contactdetail where familyheadid = @contactid
select @allheadCounttree = count(contactid) from @familyTree where familyheadid = -1
END
select * from @familyTree where city = lower('Paris') or headcity = lower('paris') order by familyid
答案 2 :(得分:-1)
select * from contactdetail where city = lower('paris')
union
select contactId, FamilyHeadId, Name, City from contactdetail cross apply (
select contactid as pcontactid, city as pcity from contactdetail where familyheadid = -1
) parentdata
where pcity = lower('paris') and pcontactid = familyheadid