这个领域已经给出了几个答案,但我想了解如何解决这个问题,当它是FOR XML Path的一部分时。
我想根据RegionID连接所有差异。我只在regionID上使用group by,但是我收到一个错误,说disppancy.description需要是聚合的一部分(使用像MAX这样的东西会扭曲我的数据),并且在group by子句中包含discrepancy.description也不准确。
<<<添加了整个查询以进一步说明>>>
select top 100
lpr.RegionID,
lpr.Region,
Max(la.LeftOffWt),
isnull(stuff((select distinct ','+coalesce(discrepancy.description,'NA')
from disConsignment as discrepancy
inner join whsHeader as wh
on wh.WhsHeaderID = discrepancy.WhsHeaderID
inner join whsConsignment as wc
on wc.whsHeaderID = wh.WhsHeaderID
inner join cgtConsignment as c
on c.[Consignment Reference] = wc.ConsignmentReference
inner join movMovement as m
on m.MovementID = wh.RunMovID
inner join dbo.genAddress as ga
on ga.AddressID = c.Consignor
inner join dbo.lstPostcode as lp
on lp.Postcode = ga.PostcodePrefix
inner join dbo.lstPostcodeRegion as lpr
on lpr.RegionID = lp.RegionID
and c.Cancelled = 0
and discrepancy.WhsHeaderID = wc.whsHeaderID
where wc.whsHeaderID = wh.whsHeaderID
and wc.StatusCode = 'NL'
and wh.ArrDepDate between @StartDate and @EndDate
and lpr.RegionID = max (lprdiscrepancy.RegionID)
for xml path('')
),1,1,''),'') as [Not Collected]
from movmovement m
inner join whsHeader wh on wh.RunMovID = m.MovementID
Inner join whsConsignment wc on wc.whsHeaderID = wh.WhsHeaderID
inner join cgtConsignment c on c.[Consignment Reference] = wc.ConsignmentReference
INNER JOIN dbo.genAddress ga ON ga.AddressID = c.Consignor
INNER JOIN dbo.lstPostcode lp ON lp.Postcode = ga.PostcodePrefix
INNER JOIN dbo.lstPostcodeRegion lpr ON lpr.RegionID = lp.RegionID
inner join disConsignment dc on dc.ConsignmentRef = c.[Consignment Reference]
Left join (SELECT lpr.RegionID, discrepancy.Description
FROM disConsignment discrepancy
inner join whsHeader wh on wh.WhsHeaderID = discrepancy.WhsHeaderID
inner join whsConsignment wc on wc.whsHeaderID = wh.WhsHeaderID
inner join cgtConsignment c on c.[Consignment Reference] = wc.ConsignmentReference
INNER JOIN dbo.genAddress ga ON ga.AddressID = c.Consignor
INNER JOIN dbo.lstPostcode lp ON lp.Postcode = ga.PostcodePrefix
INNER JOIN lstPostcodeRegion lpr ON lpr.RegionID = lp.RegionID
AND c.Cancelled = 0
AND discrepancy.WhsHeaderID = wc.whsHeaderID
WHERE wc.whsHeaderID = wh.whsHeaderID
AND wc.StatusCode IN ( 'NL' )
AND lpr.RegionID = lp.RegionID
AND wh.ArrDepDate BETWEEN @StartDate AND @EndDate
) lprdiscrepancy on lprdiscrepancy.RegionID = lpr.RegionID
LEFT JOIN ( SELECT lpr.RegionID,
SUM(c.[Chargeable Weight]) AS LeftOffWt
FROM dbo.whsConsignment wc
INNER JOIN whsHeader wh on wh.WhsHeaderID = wc.whsHeaderID
INNER JOIN dbo.cgtConsignment c ON c.[Consignment Reference] = wc.ConsignmentReference
INNER JOIN dbo.genAddress ga ON ga.AddressID = c.Consignor
INNER JOIN dbo.lstPostcode lp ON lp.Postcode = ga.PostcodePrefix
INNER JOIN dbo.lstPostcodeRegion lpr ON lpr.RegionID = lp.RegionID
AND c.Cancelled = 0
WHERE StatusCode IN ( 'NL' ) and wh.ArrDepDate between @StartDate and @EndDate
GROUP BY lpr.RegionID
) la ON la.RegionID = lp.RegionID
group by lpr.regionID, lpr.Region
ORDER BY lpr.RegionID
答案 0 :(得分:2)
由于提供给脚本的for xml
部分的数据位于子查询中,因此会针对主查询中返回的每一行运行该数据。因为它是为每一行运行的,所以您可以在子选择中引用这些值。这意味着您不需要group by
,而应将其更改为仅引用主查询中的RegionID
列:
select isnull(stuff((select distinct
','+coalesce(discrepancy.description,'NA')
from disConsignment as discrepancy
inner join whsHeader as wh
on wh.WhsHeaderID = discrepancy.WhsHeaderID
inner join whsConsignment as wc
on wc.whsHeaderID = wh.WhsHeaderID
inner join cgtConsignment as c
on c.[Consignment Reference] = wc.ConsignmentReference
inner join movMovement as m
on m.MovementID = wh.RunMovID
inner join dbo.genAddress as ga
on ga.AddressID = c.Consignor
inner join dbo.lstPostcode as lp
on lp.Postcode = ga.PostcodePrefix
inner join dbo.lstPostcodeRegion as lpr
on lpr.RegionID = lp.RegionID
and c.Cancelled = 0
and discrepancy.WhsHeaderID = wc.whsHeaderID
where wc.whsHeaderID = wh.whsHeaderID
and wc.StatusCode = 'NL'
and wh.ArrDepDate between @StartDate and @EndDate
and lpr.RegionID = <RegionID in your main query>
for xml path('')
),1,1,''),'') as [Not Collected];
回应以下评论:
with cte as
(
select lpr.RegionID
,lpr.Region
,sum(c.[Chargeable Weight]) as LeftOffWt
from dbo.whsConsignment as wc
inner join whsHeader as wh
on wh.WhsHeaderID = wc.whsHeaderID
inner join dbo.cgtConsignment as c
on c.[Consignment Reference] = wc.ConsignmentReference
inner join dbo.genAddress as ga
on ga.AddressID = c.Consignor
inner join dbo.lstPostcode as lp
on lp.Postcode = ga.PostcodePrefix
inner join dbo.lstPostcodeRegion as lpr
on lpr.RegionID = lp.RegionID
and c.Cancelled = 0
where StatusCode in('NL')
and wh.ArrDepDate between @StartDate and @EndDate
group by lpr.RegionID
,lpr.Region
)
select cte.RegionID
,cte.Region
,cte.LeftOffWt
,isnull(stuff((select distinct ',' + coalesce(d.description,'NA')
from disConsignment as d
inner join whsHeader as wh
on wh.WhsHeaderID = d.WhsHeaderID
inner join whsConsignment as wc
on wc.whsHeaderID = wh.WhsHeaderID
inner join cgtConsignment as c
on c.[Consignment Reference] = wc.ConsignmentReference
inner join movMovement as m
on m.MovementID = wh.RunMovID
inner join dbo.genAddress as ga
on ga.AddressID = c.Consignor
inner join dbo.lstPostcode as lp
on lp.Postcode = ga.PostcodePrefix
inner join dbo.lstPostcodeRegion as lpr
on lpr.RegionID = lp.RegionID
and c.Cancelled = 0
and d.WhsHeaderID = wc.whsHeaderID
where wc.whsHeaderID = wh.whsHeaderID
and wc.StatusCode = 'NL'
and wh.ArrDepDate between @StartDate and @EndDate
and lpr.RegionID = cte.RegionID
for xml path('')
),1,1,''),'') as [Not Collected]
from cte;