昨天我从一个 SO 用户那里得到了一些很棒的帮助(见这里),这让我朝着我的目标取得了很大的进步。现在我正在尝试确定是否可以将建议的神奇添加嵌入到生成 xml 输出的现有查询中。
现有查询如下:
PROCEDURE [dbo].[CreateLandingPurchaseOrderDetails]
-- Add the parameters for the stored procedure here
@startDate DATE,
@endDate DATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT (SELECT
Contacts.ContactId AS '@ContactId',
VesselOwner AS '@Owner',
FORMAT(SUM(LandingDetails.Quantity * LandingDetails.UnitPrice), 'N2') AS '@Owed',
SocietyMemberships.WeeklyDeductionRate AS '@WeeklyDeductionRate',
SocietyMemberships.FromMinimumReturn AS '@FromMinimumReturn',
Deductions.DeductionRate AS '@DeductionRate',
(SELECT DISTINCT
ld1.ProductId AS '@ProductId',
FORMAT(AVG(ld1.UnitPrice), 'N2') AS '@Cost',
FORMAT(SUM(ld1.Quantity), 'N2') AS '@Quantity'
FROM LandingDetails ld1
INNER JOIN dbo.LandingHeaders lh1
ON ld1.LandingId = lh1.LandingId
WHERE Posted = 0
AND lh1.VesselOwner = LandingHeaders.VesselOwner
GROUP BY ld1.ProductId
FOR XML PATH ('Products'), TYPE)
FROM dbo.LandingDetails
INNER JOIN dbo.LandingHeaders
ON LandingDetails.LandingId = LandingHeaders.LandingId
INNER JOIN dbo.Vessels
ON LandingHeaders.VesselId = Vessels.VesselId
INNER JOIN dbo.Contacts
ON Vessels.OwnerId = Contacts.ContactId
INNER JOIN dbo.SocietyMemberships
ON Contacts.SocietyId = SocietyMemberships.SocietyId
INNER JOIN dbo.Deductions
ON Vessels.DeductionId = Deductions.DeductionId
WHERE LandingHeaders.Posted = 0
AND LandingDate1 BETWEEN @startDate AND @endDate
GROUP BY ContactId,
VesselOwner,
SocietyMemberships.WeeklyDeductionRate,
SocietyMemberships.FromMinimumReturn,
Deductions.DeductionRate
ORDER BY ContactId
FOR XML PATH ('Owner'), TYPE)
FOR XML PATH ('PurchaseOrders'), TYPE
END
这会沿着这些线产生 xml 输出;
<PurchaseOrders>
<Owner ContactId="39" Owner="Paul Joy" Owed="1,609.39" WeeklyDeductionRate="10.00" FromMinimumReturn="110.00" DeductionRate="0.0150">
<Products ProductId="33" Cost="5.00" Quantity="0.40" />
<Products ProductId="34" Cost="1.80" Quantity="0.90" />
<Products ProductId="41" Cost="2.30" Quantity="1.30" />
我想向 Owner 元素( TotalDeductions )再添加一个属性。从我问的上一个问题中,我可以看到 sql 如何计算我所追求的信息以生成总扣除额字段。然而,将这种逻辑添加到 FOR XML 查询中被证明是难以捉摸的。我不愿意说它不能完成,因为在 SQL 中,如果有一点横向思考,似乎几乎没有什么是不能完成的。
如果我只是将查询的大小写部分剪切并粘贴到我的 FOR XML 查询中,编译器会指出 Owed 不是有效名称。我明白了。但是,如果我只是按以下方式嵌入 for xml 的所有者部分;
WITH cte AS (
'embed the part of the FOR XML producing the owner element here
)
SELECT
ContactId,
Owed,
WeeklyDeductionRate,
FromMinimumReturn,
DeductionRate,
CASE
WHEN Owed - (Owed * DeductionRate + WeeklyDeductionRate) > FromMinimumReturn
THEN Owed * DeductionRate + WeeklyDeductionRate
ELSE Owed * DeductionRate END
AS TotalDeductions
FROM cte
然后暂时将编译错误放在一边,我不会生成我所追求的 xml。
我是否终于找到了一些在 SQL 中实际上无法完成的事情,或者我只是错过了我应该有的明显的“横向想法”?
谢谢