【问题标题】:FOR XML PATH columns - concatenate every consecutive occurrence of each value to another FOR XML PATH fieldFOR XML PATH 列 - 将每个连续出现的每个值连接到另一个 FOR XML PATH 字段
【发布时间】:2019-01-10 18:59:54
【问题描述】:

目前我的结果集是由这个语句定义的

 ISNULL('| ' + [Contry],'') + ISNULL('| ' + [State],'') + ISNULL('| ' + [City],'')   
 AS ProjectLocation

上面显示的“地点”字段的当前输出如下所示:

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

附言

“YourDB.dbo.Opportunity”表表示一个包含所有可供承包商使用的项目的表

“MyDB.dbo.Contract”表是一个查找表,用于将项目与雇用的承包商联系起来。

这就是为什么我需要调用 FOR XML 函数,因为 One Opportunity 可能有多个承包商位于不同的州和城市。

目前我使用第一个语句从 CTE 中进行选择,如下所示:

SELECT
  ISNULL('| ' + [Contry],'') + ISNULL('| ' + [State],'') + ISNULL('| ' + [City],'')   
 AS ProjectLocation
FROM CTE

但正如我所说,它产生了不正确的输出。

【问题讨论】:

  • 答案取决于您的表是如何相互关联的。它可能是一个Addresses 表,所有这些表都有 FK,或者您可能在这些表中有一个层次结构。因此,如果您想要一个有意义的答案,一些示例架构和数据会很有帮助。
  • 嗨,罗杰,根据您的建议,我已为问题添加了更多上下文。希望对您有所帮助。

标签: sql-server string concatenation sql-server-2016 for-xml-path


【解决方案1】:

因此,您在单个表中拥有完整的地址。这是我期望您提供的设置:

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)
);

在这样的架构上,您需要将所有位置表连接在一起,将它们的字段组合成一个输出:

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;

【讨论】:

  • 感谢罗杰的 cmets。我同意你的提示和建议。不幸的是,这是一个现有的产品,并且架构比我在这里表示的要复杂得多。我特意简化了它,以使我的问题简明扼要。
【解决方案2】:

以下代码可以满足您的要求。我建议您维护一个名为 Geography 的表,而不是单独的国家、州、位置表。 单一的地理表将更容易维护。由于单个城市名称可以属于不同的州、国家/地区。例如。美国许多州都有贝尔维尤城市名称。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-01
    • 2023-04-09
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多