在SQL SERVER中合并两个XML CTE

时间:2019-02-14 22:52:29

标签: sql sql-server xml

我需要一些帮助在SQL Server中将两个XML CTE合并在一起。我以前使用过CTE,但是当涉及XML时,它似乎更加复杂。我感谢任何建议。

我试图基于公用密钥refid将两个XML CTE交叉应用在一起,但是没有成功。

;With TBL1_Fruits As 
(Select '1' as refid,
        'Apples' as fruits,
        'Red' as color,
        'Macintosh' as  category union
 Select  '2' as refid,
        'Oranges' as fruits,
        'Orange' as color,
        'Bergamot' as category union
 Select '3' as refid,
        'Bananas' as fruits,
        'Yellow' as color,
        'Cavendish' as category)

,TBL1_Export As
(Select 'X1234' as ShipID,
        'USA' as Country,
        'FarmersToYou' as Brand,
        '1' as refid union
 Select 'Y1234' as ShipID,
        'Costa_Rica' as Country,
        'Chiquita' as Brand,
        '3' as refid union
 Select 'Z1234' as ShipID,
        'USA' as Country,
        'Hawaiia_Sun_Tropical' as Brand,
        '2' as refid)

,TBL2_Price As
(Select '1' as refid,
        '4.50' as price,
        'lb' as unit union
 Select '2' as refid,
        '6.50' as price,
        'lb' as unit union
 Select '3' as refid,
        '2.50' as price,
        'lb' as unit)
,TBL2_Costs As
(Select '1' as refid,
        '1.50' as shipping_cost,
        '3.00' as profit,
        'lb' as unit_rev union
 Select '2' as refid,
        '3.00' as shipping_cost,
    '3.50' as profit,
    'lb' as unit_rev union
 Select '3' as refid,
        '0.50' as shipping_cost,
    '2.00' as profit,
    'lb' as unit_rev)

,XML1 As (Select * From (
Select refid, fruits, color, category,
 (Select Distinct ShipID, Country, Brand from TBL1_Export
   Where TBL1_Export.refid = TBL1_Fruits.refid
   FOR XML PATH ('FruitAttributes'),TYPE)
  From (Select Distinct refid, fruits, color, category From TBL1_Fruits) 
  TBL1_Fruits
  FOR XML PATH (''), ROOT('FruitInfo'), TYPE) As x(Fruits))

,XML2 As 
(Select * From (
Select refid, price, unit,
 (Select Distinct shipping_cost, profit, unit_rev from TBL2_Costs
   Where TBL2_Price.refid = TBL2_Costs.refid
   FOR XML PATH ('FruitProfit'),TYPE)
  From (Select Distinct refid, price, unit From TBL2_Price) TBL2_Price
  FOR XML PATH (''), ROOT('FruitRevenue'), TYPE) As c(Fruits))

如何结合使用XML1和XML2以产生以下内容:

基本上,我要寻找的是XML1之后的内容,XML2继续存在,但是与refid从XML2到XML1相匹配。如何编写此查询?

<FruitInfo>
  <refid>1</refid>
  <fruits>Apples</fruits>
  <color>Red</color>
  <category>Macintosh</category>
  <FruitAttributes>
    <ShipID>X1234</ShipID>
    <Country>USA</Country>
    <Brand>FarmersToYou</Brand>
  </FruitAttributes>
</FruitInfo>
<FruitRevenue>
  <refid>1</refid>
  <price>4.50</price>
  <unit>lb</unit>
  <FruitProfit>
    <shipping_cost>1.50</shipping_cost>
    <profit>3.00</profit>
    <unit_rev>lb</unit_rev>
  </FruitProfit>
</FruitRevenue>

1 个答案:

答案 0 :(得分:0)

我认为您已经把这个复杂化了...试试这个:

假设您的CTE是表的模拟,为了便于阅读,我对此进行了更改:

DECLARE @TBL1_Fruits TABLE(refid INT,fruits VARCHAR(100),color VARCHAR(100),category VARCHAR(100));
INSERT INTO @TBL1_Fruits(refid,fruits,color,category) 
(Select '1' as refid,
        'Apples' as fruits,
        'Red' as color,
        'Macintosh' as  category union
 Select  '2' as refid,
        'Oranges' as fruits,
        'Orange' as color,
        'Bergamot' as category union
 Select '3' as refid,
        'Bananas' as fruits,
        'Yellow' as color,
        'Cavendish' as category);

DECLARE @TBL1_Export TABLE(ShipID VARCHAR(100),Country VARCHAR(100),Brand VARCHAR(100),refid INT);
INSERT INTO @TBL1_Export(ShipID,Country,Brand,refid)
(Select 'X1234' as ShipID,
        'USA' as Country,
        'FarmersToYou' as Brand,
        '1' as refid union
 Select 'Y1234' as ShipID,
        'Costa_Rica' as Country,
        'Chiquita' as Brand,
        '3' as refid union
 Select 'Z1234' as ShipID,
        'USA' as Country,
        'Hawaiia_Sun_Tropical' as Brand,
        '2' as refid);

DECLARE @TBL2_Price TABLE(refid INT,price DECIMAL(10,4),unit VARCHAR(100));
INSERT INTO @TBL2_Price(refid,price,unit)
(Select '1' as refid,
        '4.50' as price,
        'lb' as unit union
 Select '2' as refid,
        '6.50' as price,
        'lb' as unit union
 Select '3' as refid,
        '2.50' as price,
        'lb' as unit);

DECLARE @TBL2_Costs TABLE(refid INT,shipping_cost DECIMAL(10,4),profit DECIMAL(10,4),unit_rev VARCHAR(100))
INSERT INTO @TBL2_Costs(refid,shipping_cost,profit,unit_rev)
(Select '1' as refid,
        '1.50' as shipping_cost,
        '3.00' as profit,
        'lb' as unit_rev union
 Select '2' as refid,
        '3.00' as shipping_cost,
    '3.50' as profit,
    'lb' as unit_rev union
 Select '3' as refid,
        '0.50' as shipping_cost,
    '2.00' as profit,
    'lb' as unit_rev);

-如果我正确理解了这一点,则可以使用嵌套路径而不是子查询来实现:

SELECT e.refid AS [FruitInfo/refid]
      ,f.fruits AS [FruitInfo/fruits]
      ,f.color AS [FruitInfo/color]
      ,f.category AS [FruitInfo/category]
      ,e.ShipID AS [FruitInfo/FruitAttributes/ShipID]
      ,e.Country AS [FruitInfo/FruitAttributes/Country]
      ,e.Brand AS [FruitInfo/FruitAttributes/Brand]
      ,e.refid AS [FruitRevenue/refid]
      ,p.price AS [FruitRevenue/price]
      ,p.unit AS [FruitRevenue/unit]
      ,c.shipping_cost AS [FruitRevenue/FruitProfit/shipping_unit]
      ,c.profit AS [FruitRevenue/FruitProfit/profit]
      ,c.unit_rev AS [FruitRevenue/FruitProfit/unit_rev]
FROM @TBL1_Export e
INNER JOIN @TBL1_Fruits f ON e.refid=f.refid
INNER JOIN @TBL2_Costs c ON e.refid=c.refid
INNER JOIN @TBL2_Price p ON e.refid=p.refid
WHERE e.refid=1 --<-- Remove this to get all at once
FOR XML PATH('')
--Or use this to get your XML in appropritate nestings
--FOR XML PATH('Fruit'),ROOT('Fruits')

结果(部分结果)

<FruitInfo>
  <refid>1</refid>
  <fruits>Apples</fruits>
  <color>Red</color>
  <category>Macintosh</category>
  <FruitAttributes>
    <ShipID>X1234</ShipID>
    <Country>USA</Country>
    <Brand>FarmersToYou</Brand>
  </FruitAttributes>
</FruitInfo>
<FruitRevenue>
  <refid>1</refid>
  <price>4.5000</price>
  <unit>lb</unit>
  <FruitProfit>
    <shipping_unit>1.5000</shipping_unit>
    <profit>3.0000</profit>
    <unit_rev>lb</unit_rev>
  </FruitProfit>
</FruitRevenue>

但是您的问题有很多悬而未决的问题:

refid是链接表之间的最佳列吗?水果在任何情况下都不会具有相同的价格,运输也不会相同...我认为您应该在出口表中使用水果表的ID作为FK,但在价格表中使用ShipID作为FK(与成本相同) 。这样每次运送的价格和成本都会不同。

在大多数情况下,您会找到一个日期为valid_to的价格表,其中某个产品已定价,而给定货件中使用的价格可能会有所不同(由于协商而定)。