FOR XML PATH 列 - 将每个连续出现的每个值连接到另一个 FOR XML PATH 字段
FOR XML PATH columns - concatenate every consecutive occurrence of each value to another FOR XML PATH field
目前我的结果集是由这条语句定义的
ISNULL('| ' + [Contry],'') + ISNULL('| ' + [State],'') + ISNULL('| ' + [City],'')
AS ProjectLocation
上面显示的 "Place" 文件的当前输出如下所示:
United States, United States, United States| California, Hawaii, Virginia| Norfolk, Pearl Harbor, San Diego,
我需要这样的输出:
United States, Hawaii, Pearl Harbor | United States, Virginia, Norfolk | United States, California, San Diego
上面调用的列的值是根据FOR XML PATH('')
函数定义的,如下所示:
WITH CTE AS
(
SELECT
(SELECT Country.CountryName + ', '
FROM MyDB.dbo.Country c
INNER JOIN MyDB.dbo.Contract con ON c.CountryID = con.ContryID
AND Opp.OppID = Con.OppID
FOR XML PATH('')) AS Country,
(SELECT State.StateName + ', '
FROM MyDB.dbo.State s
INNER JOIN MyDB.dbo.Contract con ON s.StateID = con.ContryID
AND Opp.OppID = Con.OppID
FOR XML PATH('')) AS State,
(SELECT State.StateAbbr + ', '
FROM MyDB.dbo.State s
INNER JOIN MyDB.dbo.Contract con ON s.StateID = con.ContryID
AND Opp.OppID = Con.OppID
FOR XML PATH('')) AS StateCode,
(SELECT Location.LocationName + ', '
FROM MyDB.dbo.Location l
INNER JOIN MyDB.dbo.Contract con ON l.LocationID= con.LocationID
AND Opp.OppID = Con.OppID
FOR XML PATH('')) AS City
FROM ''"
YourDB.dbo.Opportunity Opp
)
SELECT ...
FROM CTE
P.S.
"YourDB.dbo.Opportunity" table 表示 table 包含可供承包商使用的所有项目
"MyDB.dbo.Contract" table 是一个查找 table,它将项目与雇佣的承包商结合起来。
所以这就是为什么我需要调用 FOR XML Function as One Opportunity 可能有位于不同州和城市的多个承包商。
目前我使用来自 CTE 的第一个声明 select 如下:
SELECT
ISNULL('| ' + [Contry],'') + ISNULL('| ' + [State],'') + ISNULL('| ' + [City],'')
AS ProjectLocation
FROM CTE
但正如我所说,它产生了错误的输出。
下面的代码可以很好地满足您的要求。我建议您维护一个名为 Geography 的 table,而不是单独的国家、州、位置 table。
单一地域 table 将更易于维护。作为一个城市名称,可以属于不同的州、国家。例如。贝尔维尤城市名称出现在美国的许多州。
CREATE TABLE #Opportunity(OpportunityId int)
INSERT INTO #Opportunity values(1);
CREATE TABLE #Contract(ContractID int, OpportunityID int, CountryId int, StateId int, locationId int )
INSERT INTO #Contract values(1,1,1,1,1),(2,1,1,2,2);
CREATE TABLE #Country(CountryId int, CountryName VARCHAR(10))
INSERT INTO #Country values (1,'USA');
CREATE TABLE #State(StateId int, StateName VARCHAR(10))
INSERT INTO #State values (1,'California'),(2,'Washington');
CREATE TABLE #Location(LocationId int, LocationName VARCHAR(10))
INSERT INTO #Location values (1,'LosAngeles'),(2,'Bellevue');
SELECT c.OpportunityId, c.ContractId, STUFF( (SELECT ','+ CONCAT(CountryName,',',statename,',',locationName)
FROM #Country AS cn
left JOIN #State as s
ON c.StateId = s.StateId
left JOIN #Location AS l
ON c.LocationId = l.LocationId
WHERE c.CountryId = cn.CountryId),1,1,'')
FROM #Contract As c
所以你在一个 table 中有一个完整的地址。这是我希望您提供的设置:
declare @Country table (Id int, Name varchar(100));
declare @State table (Id int, Name varchar(100));
declare @Location table (Id int, Name varchar(100));
declare @Opp table (
Id int,
CountryId int,
StateId int,
LocationId int,
OpportunityDescription varchar(100)
);
在这样的架构上,您需要将所有位置 table 连接在一起,将它们的字段组合成一个输出:
select op.*, (
select concat(c.Name, s.Name, l.Name) as [data()]
from @Opp p
inner join @Country c on c.Id = p.CountryId
inner join @State s on s.Id = p.StateId
inner join @Location l on l.Id = p.LocationId
where p.Id = op.Id
for xml path('')
) as [OpportunityLocation]
from @Opp op;
目前我的结果集是由这条语句定义的
ISNULL('| ' + [Contry],'') + ISNULL('| ' + [State],'') + ISNULL('| ' + [City],'')
AS ProjectLocation
上面显示的 "Place" 文件的当前输出如下所示:
United States, United States, United States| California, Hawaii, Virginia| Norfolk, Pearl Harbor, San Diego,
我需要这样的输出:
United States, Hawaii, Pearl Harbor | United States, Virginia, Norfolk | United States, California, San Diego
上面调用的列的值是根据FOR XML PATH('')
函数定义的,如下所示:
WITH CTE AS
(
SELECT
(SELECT Country.CountryName + ', '
FROM MyDB.dbo.Country c
INNER JOIN MyDB.dbo.Contract con ON c.CountryID = con.ContryID
AND Opp.OppID = Con.OppID
FOR XML PATH('')) AS Country,
(SELECT State.StateName + ', '
FROM MyDB.dbo.State s
INNER JOIN MyDB.dbo.Contract con ON s.StateID = con.ContryID
AND Opp.OppID = Con.OppID
FOR XML PATH('')) AS State,
(SELECT State.StateAbbr + ', '
FROM MyDB.dbo.State s
INNER JOIN MyDB.dbo.Contract con ON s.StateID = con.ContryID
AND Opp.OppID = Con.OppID
FOR XML PATH('')) AS StateCode,
(SELECT Location.LocationName + ', '
FROM MyDB.dbo.Location l
INNER JOIN MyDB.dbo.Contract con ON l.LocationID= con.LocationID
AND Opp.OppID = Con.OppID
FOR XML PATH('')) AS City
FROM ''"
YourDB.dbo.Opportunity Opp
)
SELECT ...
FROM CTE
P.S.
"YourDB.dbo.Opportunity" table 表示 table 包含可供承包商使用的所有项目
"MyDB.dbo.Contract" table 是一个查找 table,它将项目与雇佣的承包商结合起来。
所以这就是为什么我需要调用 FOR XML Function as One Opportunity 可能有位于不同州和城市的多个承包商。
目前我使用来自 CTE 的第一个声明 select 如下:
SELECT
ISNULL('| ' + [Contry],'') + ISNULL('| ' + [State],'') + ISNULL('| ' + [City],'')
AS ProjectLocation
FROM CTE
但正如我所说,它产生了错误的输出。
下面的代码可以很好地满足您的要求。我建议您维护一个名为 Geography 的 table,而不是单独的国家、州、位置 table。 单一地域 table 将更易于维护。作为一个城市名称,可以属于不同的州、国家。例如。贝尔维尤城市名称出现在美国的许多州。
CREATE TABLE #Opportunity(OpportunityId int)
INSERT INTO #Opportunity values(1);
CREATE TABLE #Contract(ContractID int, OpportunityID int, CountryId int, StateId int, locationId int )
INSERT INTO #Contract values(1,1,1,1,1),(2,1,1,2,2);
CREATE TABLE #Country(CountryId int, CountryName VARCHAR(10))
INSERT INTO #Country values (1,'USA');
CREATE TABLE #State(StateId int, StateName VARCHAR(10))
INSERT INTO #State values (1,'California'),(2,'Washington');
CREATE TABLE #Location(LocationId int, LocationName VARCHAR(10))
INSERT INTO #Location values (1,'LosAngeles'),(2,'Bellevue');
SELECT c.OpportunityId, c.ContractId, STUFF( (SELECT ','+ CONCAT(CountryName,',',statename,',',locationName)
FROM #Country AS cn
left JOIN #State as s
ON c.StateId = s.StateId
left JOIN #Location AS l
ON c.LocationId = l.LocationId
WHERE c.CountryId = cn.CountryId),1,1,'')
FROM #Contract As c
所以你在一个 table 中有一个完整的地址。这是我希望您提供的设置:
declare @Country table (Id int, Name varchar(100));
declare @State table (Id int, Name varchar(100));
declare @Location table (Id int, Name varchar(100));
declare @Opp table (
Id int,
CountryId int,
StateId int,
LocationId int,
OpportunityDescription varchar(100)
);
在这样的架构上,您需要将所有位置 table 连接在一起,将它们的字段组合成一个输出:
select op.*, (
select concat(c.Name, s.Name, l.Name) as [data()]
from @Opp p
inner join @Country c on c.Id = p.CountryId
inner join @State s on s.Id = p.StateId
inner join @Location l on l.Id = p.LocationId
where p.Id = op.Id
for xml path('')
) as [OpportunityLocation]
from @Opp op;