1

我很难弄清楚如何将 XML PATH 添加到我的代码中以连接一些信息,更不用说理解 XML PATH 的工作原理了。在过去两天的大部分时间里,我都在努力解决这个问题,希望能得到一些帮助!

这是我正在使用的代码:

Select Top 100 Percent Agreements.AgrmntID, Agreements.Description As
  AgrmntDesc, Agreements.Status, AgreementSchedules.SchedDate, DateName(dw,
  AgreementSchedules.SchedDate), LaborCodeTypes.Description As LaborCode,
  Customers.CustName, Customers.CompanyName, JobSites.SiteName,
  AgreementSchedules.AgrmntSchedID
From Agreements Inner Join
  AgreementTypes On Agreements.AgrmntTypeID = AgreementTypes.AgrmntTypeID
  Inner Join
  AgreementSchedules On Agreements.AgrmntID = AgreementSchedules.AgrmntID
  Inner Join
  Customers On Agreements.CustID = Customers.CustID Inner Join
  JobSites On Agreements.CustSiteID = JobSites.CustSiteID Left Outer Join
  LaborCodeTypes On AgreementSchedules.RepairID = LaborCodeTypes.RepairID
Where Agreements.Status = 2 And Month(AgreementSchedules.SchedDate) =
  Month(GetDate())

样本数据:

| AgreementID | LaborCodeTypes.Description   | DateName(dw, AgreementSchedules.SchedDate)|
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -|
| 1           | Landscaping                  | Tuesday                                   |
| 1           | Landscaping                  | Friday                                    |
| 1           | Sweeping                     | Monday                                    |
| 1           | Sweeping                     | Wednesday                                 |
| 1           | Sweeping                     | Friday                                    |
| 2           | Landscaping                  | Monday                                    |

预期输出:

| AgreementID | LaborCode   | Days Of Week              |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| 1           | Landscaping | Tuesday, Friday           |
| 1           | Sweeping    | Monday, Wednesday, Friday |
| 2           | Landscaping | Monday                    |

如果有人可以帮助我,我将不胜感激。

先感谢您!!

杰米小号

4

3 回答 3

3

XML PATH 的工作原理

我将尝试使用此设置来解释:

create table Grp
(
  GrpID int primary key,
  Name varchar(10)
)

create table Item
(
  ItemID int identity primary key,
  Name varchar(10),
  GrpID int references Grp(GrpID)
)

insert into Grp values
(1, 'G1'),
(2, 'G2')

insert into Item values
('A', 1),
('B', 1),
('C', 1),
('D', 2),
('E', 2)

目标是为每个组创建一个以逗号分隔的名称列表的结果。

GroupName  ItemNames
---------- ----------
G1         A,B,C
G2         D,E

FOR XML用于将查询结果转换为 XML 文档或 XML 片段。

此查询将创建一个 XML 片段。

select I.Name
from Item as I
for xml path(''), type

结果:

<Name>A</Name>
<Name>B</Name>
<Name>C</Name>
<Name>D</Name>
<Name>E</Name>

上面的查询可以用在相关的子查询中,像这样为每个组创建 XML 片段。

select G.Name as GroupName,
       (
         select I.Name
         from Item as I
         where G.GrpID = I.GrpID
         for xml path(''), type
       ) as ItemNames
from Grp as G

结果:

GroupName  ItemNames
---------- --------------------------------------------
G1         <Name>A</Name><Name>B</Name><Name>C</Name>
G2         <Name>D</Name><Name>E</Name>

然后,您可以使用value()函数提取 XML 中的值。

select Name as GroupName,
       (
         select I.Name
         from Item as I
         where G.GrpID = I.GrpID
         for xml path(''), type
       ).value('.', 'varchar(max)') as ItemNames
from Grp as G

结果:

GroupName  ItemNames
---------- ----------
G1         ABC
G2         DE

要完成此操作,您需要添加逗号作为分隔符,这可以通过在子查询中的每个项目名称中添加逗号来完成select ','+I.Name。它会在第一个值之前为您留下一个额外的逗号。您可以使用STUFF功能将其删除STUFF(Value, 1, 1, '')

最终查询:

select Name as GroupName,
       stuff((
         select ','+I.Name
         from Item as I
         where G.GrpID = I.GrpID
         for xml path(''), type
       ).value('.', 'varchar(max)'), 1, 1, '') as ItemNames
from Grp as G
于 2012-08-29T07:47:07.897 回答
2
;with C as
(
  select A.AgreementID,
         LCT.Description as LaborCode,
         Ags.ShedDate
  from Agreements as A
    inner join AgreementSchedules as AgS
      on A.AgreementID = AgS.AgreementID
    inner join LaborCodeTypes as LCT
      on AgS.RepairID = LCT.RepairID
  where A.[Status] = 2 and
        AgS.ShedDate >= dateadd(month, datediff(month, 0, getdate()), 0) and
        AgS.ShedDate < dateadd(month, 1+datediff(month, 0, getdate()), 0)
)
select C1.AgreementID,
       C1.LaborCode,
       stuff((select ', '+datename(weekday, C2.ShedDate)
              from C as C2
              where C1.AgreementID = C2.AgreementID and
                    C1.LaborCode = C2.LaborCode
              order by C2.ShedDate
              for xml path(''), type).value('.', 'varchar(max)'), 1, 2, '') as [Days Of Week]
from C as C1
group by C1.AgreementID, C1.LaborCode;

SQL小提琴

于 2012-08-30T05:28:20.663 回答
0

我相信我有不同的方式来实现你正在寻找的结果......

SELECT * FROM (
    SELECT DISTINCT AgreementId, UPPER(Description), 1 AS IsLabor
    FROM Table
    WHERE ...
    UNION
    SELECT AgreementId, DateName AS Description, 0 AS IsLabor
    FROM Table
    WHERE ...
) x
ORDER BY AgreementId, IsLabor DESC, Description

这应该输出以下内容(UPPER 只是为了强调劳动描述):

| AgreementId | Description | IsLabor |
---------------------------------------
| 1           | LANDSCAPING | 1       |
| 1           | Friday      | 0       |
| 1           | Tuesday     | 0       |
| 2           | SWEEPING    | 1       |
| 2           | Friday      | 0       |
| 2           | Monday      | 0       |
| 2           | Wednesday   | 0       |

希望我理解你的问题,这会奏效。

于 2012-08-29T03:38:31.463 回答