带有嵌套查询的XML输出,用于xml显式或路径

时间:2014-07-03 15:28:21

标签: sql xml tsql

我今天在T-sql中写了一个完全正常的查询。对于客户,我需要以XML格式提供数据。我尝试使用显式方法和路径方法,但没有任何成功。

我的查询如下:

select 
    allShopsItem.ShopCode as ShopCode
    , allShopsItem.ItemCode as ItemCode
    , allShopsItem.SupplyNumber as SupplyNumber
    , CONVERT (date, GETDATE()-1) as Fulldate
    , isnull(sales.SumQtyTransactions, 0) as Sales
    , isnull(stock.Qty, 0) as Stock
    , isnull(outstandingorders.sumQTY, 0) as Outstanding
from (
        select 
            S.SHOP_CODE as ShopCode, 
            I.ITEM_CODE as ItemCode,
            I.ITEM_NAME as ItemName,
            CVI.CUSTVENDRELATION as SupplyNumber
        from 
            BI_DWH_BC.D_SHOP S
            CROSS JOIN BI_DWH_BC.D_ITEM I
            INNER JOIN BI_STAGING.ERP_CUSTVENDEXTERNALITEM CVI
            ON I.ITEM_CODE = CVI.ITEMID AND CVI.CUSTVENDRELATION = 900520
        WHERE 
            I.ITEM_GRP_CODE = 'HW-ACC' /*and I.ITEM_CYCLE = 'Normaal'*/ and I.ROW_IS_CURRENT = 1 
            AND S.SHOP_TYPE IN ('Telenet Store','Telenet Concept Store')
            AND S.SHOP_IS_CLOSED = 0
        ) as allShopsItem
LEFT OUTER JOIN (
        SELECT 
            S.SHOP_CODE as ShopCode, 
            I.ITEM_CODE as ItemCode,
            CAST(SUM(TR.TRANS_QUANTITY*-1) AS INTEGER) as SumQtyTransactions
        FROM 
            BI_DWH_BC.F_TRANSACTION TR
                INNER JOIN BI_DWH_BC.D_DATE D ON D.PK_DATE = TR.FK_TRANS_DATE
                INNER JOIN BI_DWH_BC.D_SHOP S ON S.PK_SHOP = TR.FK_TRANS_SHOP
                INNER JOIN BI_DWH_BC.D_ITEM I ON I.PK_ITEM = TR.FK_TRANS_ITEM
        WHERE
            D.DATE_FULLDATE = CONVERT (date, GETDATE()-1)  
            --TR.FK_TRANS_DATE = 20140702  
        GROUP BY 
            S.SHOP_CODE, I.ITEM_CODE
                ) as sales ON allShopsItem.ShopCode = sales.ShopCode AND allShopsItem.ItemCode = sales.ItemCode

LEFT OUTER JOIN (
        SELECT
            S.SHOP_CODE as ShopCode
            , IT.ITEM_CODE as ItemCode
            , SUM(SM.STMOV_QTY) Qty
        FROM BI_DWH_BC.F_STOCK_MOVEMENT SM
            INNER JOIN BI_DWH_BC.D_DATE D ON D.PK_DATE = SM.FK_STMOV_DATE
            INNER JOIN BI_DWH_BC.D_ITEM IT ON IT.PK_ITEM = SM.FK_STMOV_ITEM
            INNER JOIN BI_DWH_BC.D_SHOP S ON S.PK_SHOP = SM.FK_STMOV_SHOP
        WHERE 
            D.DATE_FULLDATE <= CONVERT (date, GETDATE()-1)  
        GROUP BY 
            S.SHOP_CODE, IT.ITEM_CODE
        HAVING 
            SUM(SM.STMOV_QTY) <> 0
                )  as stock ON allShopsItem.ShopCode = stock.ShopCode AND allShopsItem.ItemCode = stock.ItemCode

LEFT OUTER JOIN (
        SELECT 
            S.SHOP_CODE as ShopCode, 
            PL.ITEMID  as ItemID,
            SUM(CAST(PL.REMAINPURCHPHYSICAL AS INTEGER)) as sumQTY
        FROM 
            BI_STAGING.ERP_PURCHLINE PL
                INNER JOIN BI_STAGING.ERP_PURCHTABLE PT ON PT.PURCHID = PL.PURCHID
                LEFT OUTER JOIN BI_STAGING.ERP_VENDTABLECUBE V ON PT.INVOICEACCOUNT = V.ACCOUNTNUM
                LEFT OUTER JOIN BI_DWH_BC.D_SHOP S ON S.SHOP_CODE = RIGHT(PT.INVENTLOCATIONID,3)
        WHERE 
            PL.REMAINPURCHPHYSICAL <> 0 AND PL.QTYORDERED <> 0
        GROUP BY 
            S.SHOP_CODE, PL.ITEMID
                ) as outstandingorders ON allShopsItem.ShopCode = outstandingorders.ShopCode AND allShopsItem.ItemCode = outstandingorders.ItemID

GROUP BY 
    allShopsItem.ShopCode, allShopsItem.ItemCode,allShopsItem.SupplyNumber, sales.SumQtyTransactions, stock.Qty, outstandingorders.sumQTY
ORDER BY 
    allShopsItem.ShopCode, allShopsItem.ItemCode

以下示例的输出可通过以下示例进行比较:

shopcode  itemcode  Sales  Stock
--------  --------  -----  -----
0013       121212     2      1
0013       122224     3      2
0032       121545     1      1
0032       121211     2      5 

现在我需要以下xml:

<shopcode>
    <itemcode>
        <sales>
        </sales>
        <stock>
        </stock>
    </itemcode>
     <itemcode>
        <sales>
        </sales>
        <stock>
        </stock>
    </itemcode>
</shopcode>

简而言之,我想要概述每个商店的所有商品。 有人在我的查询中进行一些调整后,是否知道如何以相对简单的方式做到这一点?

提前致谢!

2 个答案:

答案 0 :(得分:0)

我不确定您希望XML结构如何(例如,您是否需要将商店/商品代码作为属性?),但这样的内容可能对您有用..

SELECT
    S.SHOP_CODE AS [@code],
    (
        SELECT
            ITEM_CODE AS [@code],
            (
                SELECT ISNULL((
                    SELECT CAST(SUM(TR.TRANS_QUANTITY * -1) AS INT)
                    FROM BI_DWH_BC.F_TRANSACTION TR
                    INNER JOIN BI_DWH_BC.D_DATE D
                        ON D.PK_DATE = TR.FK_TRANS_DATE
                    INNER JOIN BI_DWH_BC.D_SHOP S2
                        ON S2.PK_SHOP = TR.FK_TRANS_SHOP
                    INNER JOIN BI_DWH_BC.D_ITEM I2
                        ON I2.PK_ITEM = TR.FK_TRANS_ITEM
                    WHERE D.DATE_FULLDATE = CONVERT(DATE, GETDATE()-1)  
                    AND S2.SHOP_CODE = S.SHOP_CODE
                    AND I2.ITEM_CODE = I.ITEM_CODE
                    GROUP BY S2.SHOP_CODE, I2.ITEM_CODE                 
                ), 0)
                FOR XML PATH ('sales'), TYPE
            ),
            (
                SELECT ISNULL((
                    SELECT
                        SUM(SM.STMOV_QTY) Qty
                    FROM BI_DWH_BC.F_STOCK_MOVEMENT SM
                    INNER JOIN BI_DWH_BC.D_DATE D2
                        ON D2.PK_DATE = SM.FK_STMOV_DATE
                    INNER JOIN BI_DWH_BC.D_ITEM IT
                        ON IT.PK_ITEM = SM.FK_STMOV_ITEM
                    INNER JOIN BI_DWH_BC.D_SHOP S2
                        ON S2.PK_SHOP = SM.FK_STMOV_SHOP
                    WHERE D2.DATE_FULLDATE <= CONVERT(DATE, GETDATE()-1)  
                    AND S2.SHOP_CODE = S.SHOP_CODE
                    AND IT.ITEM_CODE = I.ITEM_CODE
                    GROUP BY S2.SHOP_CODE, IT.ITEM_CODE
                    HAVING SUM(SM.STMOV_QTY) <> 0
                ), 0)
                FOR XML PATH('stock'), TYPE
            )
        FROM BI_DWH_BC.D_ITEM I
        INNER JOIN BI_STAGING.ERP_CUSTVENDEXTERNALITEM CVI
            ON I.ITEM_CODE = CVI.ITEMID
            AND CVI.CUSTVENDRELATION = 900520
        WHERE I.ITEM_GRP_CODE = 'HW-ACC'
        AND I.ROW_IS_CURRENT = 1
        FOR XML PATH('item'), TYPE
    )
FROM BI_DWH_BC.D_SHOP S
WHERE S.SHOP_TYPE IN ('Telenet Store','Telenet Concept Store')
AND S.SHOP_IS_CLOSED = 0
FOR XML PATH('shop')

输出:

<shop code="13">
  <item code="121212">
    <sales>0</sales>
    <stock>0</stock>
  </item>
  <item code="122224">
    <sales>0</sales>
    <stock>0</stock>
  </item>
</shop>
<shop code="32">
  <item code="121212">
    <sales>0</sales>
    <stock>0</stock>
  </item>
  <item code="122224">
    <sales>0</sales>
    <stock>0</stock>
  </item>
</shop>

答案 1 :(得分:0)

汤姆的回答看起来不错。作为替代方案,您可以将没有xml指令的原始humungous查询封装为视图或CTE,然后查询它以形成xml。就像汤姆提到的那样,你的样本输出在商店代码和商品代码方面没有多大意义,但你可以从这里调整。另外,我将输出包装在根节点中:

;WITH SRC(shopcode, itemcode, sales, stock) AS
(
  SELECT TOP 100 PERCENT shopcode, itemcode, sales, stock 
    FROM <MyHumungousViewOrQuery>
   ORDER BY shopcode, itemcode
),
SHOPS(shopcode) AS (SELECT DISTINCT shopcode FROM SRC)

SELECT  shopcode AS [@code],
        (
        SELECT itemcode AS [@code],
               (
               SELECT sales AS [sales],
                      stock AS [stock]
                  FROM SRC details WHERE details.shopcode = items.shopcode AND details.itemcode = items.itemcode
                   FOR XML PATH(''), TYPE
               ) 
          FROM SRC items WHERE items.shopcode = SHOPS.shopcode
           FOR XML PATH('itemcode'), TYPE
        )
  FROM SHOPS
   FOR XML PATH('shopcode'), ROOT('shops')

收率:

<shops>
  <shopcode code="0013">
    <itemcode code="121212">
      <sales>2</sales>
      <stock>1</stock>
    </itemcode>
    <itemcode code="122224">
      <sales>3</sales>
      <stock>2</stock>
    </itemcode>
  </shopcode>
  <shopcode code="0032">
    <itemcode code="121545">
      <sales>1</sales>
      <stock>1</stock>
    </itemcode>
    <itemcode code="121211">
      <sales>2</sales>
      <stock>5</stock>
    </itemcode>
  </shopcode>
</shops>