【问题标题】:How to combine two FOR XML AUTO into 1 XML?如何将两个 FOR XML AUTO 组合成 1 个 XML?
【发布时间】:2020-07-08 10:02:46
【问题描述】:

我们使用的是 SQL Server 2012。

  • myTbl 与表myAllocation 具有一对多关系
  • ABC_myTbl 与表ABC_myAllocation 具有一对多关系

下面的查询将 2 个 FOR XML AUTO 合并为 1 个 XML,但问题是 ID、SystemSource、Manager 不是单独包含在元素 TradeTicket 中,而 accountManager、unitPrice 不是单独包含在元素 allocationRow 中。

谢谢

        SELECT '<?xml version="1.0"?>'+
    (SELECT 
            (   SELECT trTicket.[id],trTicket.[manager],'PFM' as SystemSource
                    ,allocationRow.accountNumber,allocationRow.unitPrice
                FROM myTbl AS trTicket 
                LEFT JOIN myAllocation AS allocationRow ON allocationRow.trade_ticket_id=trTicket.id
                    WHERE trTicket.ID = 8779631
                    ORDER BY trTicket.id,allocationRow.AccountNumber
                FOR XML AUTO, type)
            ,
            (
                SELECT trTicket.[id],trTicket.[manager],'CRD' as SystemSource
                    ,allocationRow.accountNumber,allocationRow.unitPrice
                FROM ABC_myTbl AS trTicket 
                LEFT JOIN ABC_myAllocation AS allocationRow ON allocationRow.trade_ticket_id=trTicket.id
                    WHERE trTicket.ID = 8
                    ORDER BY trTicket.id,allocationRow.AccountNumber
                FOR XML AUTO, type)
    FOR XML PATH('trTickets'), ELEMENTS) AS XMLResult

这是当前结果:

<?xml version="1.0"?>
<trTickets>
<trTicket id="8779631" SystemSource="PFM" manager="MCM">
<allocationRow accountNumber="292 " unit_Price="300"/>
</trTicket>
<trTicket id="8" SystemSource="CRD" manager="DOYLE">
<allocationRow unitPrice="100" accountNumber="F11 "/>
<allocationRow unitPrice="200" accountNumber="F22 "/>
</trTicket>
</trTickets>

这是我想要的结果:

    <?xml version="1.0"?>
    <trTickets>
    <trTicket>
    <id>8</id>
    <manager>DOYLE</manager>
    <SystemSource>CRD</SystemSource>
    <allocationRow>
    <accountNumber>F11</accountNumber>
    <unitPrice>100</unitPrice>
    </allocationRow>
    <allocationRow>
    <accountNumber>F22</accountNumber>
    <unitPrice>200</unitPrice>
    </allocationRow>
    </trTicket>
    <trTicket>
    <id>8779631</id>
    <manager>MCM</manager> 
    <SystemSource>PFM</SystemSource>
    <allocationRow>
    <accountNumber>292</accountNumber>
    <unitPrice>300</unitPrice>
    </allocationRow>
    </trTicket>
    </trTickets>

数据样本:

ABC_myTbl:

ID  Manager
-----------
8   DOYLE

ABC_myAllocation:

accountNumber   unitPrice
-------------------------
F11             100
F22             200

myTbl

ID      Manager
--------------- 
8779631 MCM

myAllocation

accountNumber   unitPrice
--------------------------
292             300

表及其数据的 DDL:

CREATE TABLE dbo.ABC_myTbl 
(
    ID INT  NOT NULL,
    MANAGER VARCHAR(10) NOT NULL
)

CREATE TABLE dbo.myTbl 
(
    ID INT  NOT NULL,
    MANAGER VARCHAR(10) NOT NULL
)   

CREATE TABLE dbo.ABC_myAllocation
(
    accountNumber VARCHAR(10) NOT NULL,
    unitprice     NUMERIC(10, 3) NOT NULL
)

CREATE TABLE dbo.myAllocation
(
    accountNumber VARCHAR(10) NOT NULL,
    unitprice     NUMERIC(10, 3)  NOT NULL
)

INSERT INTO dbo.ABC_myTbl VALUES (8,'DOYLE')

INSERT INTO dbo.ABC_myAllocation VALUES ('F11',100)
INSERT INTO dbo.ABC_myAllocation VALUES ('F22',200)

INSERT INTO dbo.myTbl VALUES (8779631,'MCM')

INSERT INTO dbo.myAllocation  VALUES  ('292',300)

【问题讨论】:

  • 如果您能提供一个最小的可重现样本,那就太好了:(1) DDL 和样本数据填充,即 CREATE 表加上 INSERT、T-SQL 语句。 (2) 你需要做什么,即逻辑。 (3) 基于上述#1 的样本数据的期望输出。 (4) 你的 SQL Server 版本 (SELECT @@version;)
  • 您好,我在原始帖子中添加了表格及其数据的 DDL。我想要的 XML 输出列在文章的末尾。谢谢。

标签: sql-server xml tsql sql-server-2012 xquery


【解决方案1】:

我没有等待您的 DDL 和样本数据填充。所以我为你创建了一个概念样本。请注意,这些表具有隐含关系,它们用于WHERE 子句中。

SQL

-- DDL and sample data population, start
DECLARE @tbl1 TABLE (ID INT PRIMARY KEY, Manager VARCHAR(20));
INSERT INTO @tbl1 (ID, Manager) VALUES
(8, 'DOYLE'),
(9, 'XYZ');

DECLARE @tbl1Child TABLE (accountNumber CHAR(3) PRIMARY KEY, ParentID INT, unitPrice DECIMAL(10,2));
INSERT INTO @tbl1Child (accountNumber, ParentID, unitPrice) VALUES
('F11', 8, 100)
,('F22', 8, 200)
,('F70', 9, 770);

DECLARE @tbl2 TABLE (ID INT PRIMARY KEY, Manager VARCHAR(20));
INSERT INTO @tbl2 (ID, Manager) VALUES
(8779631, 'MCM')
,(8779555, 'TTT');

DECLARE @tbl2Child TABLE (accountNumber CHAR(3) PRIMARY KEY, ParentID INT, unitPrice DECIMAL(10,2));
INSERT INTO @tbl2Child (accountNumber, ParentID, unitPrice) VALUES
('292', 8779631, 300)
,('255', 8779555, 500);
-- DDL and sample data population, end

SELECT TOP(1) NULL
, (
    SELECT *
        , (
            SELECT * FROM @tbl1Child AS c
            WHERE p.ID = c.ParentID
            FOR XML PATH('allocation_row'), TYPE
        ) 
    FROM @tbl1 AS p
    FOR XML PATH('tradeTicket'), TYPE
)
, (
    SELECT *
        , (
            SELECT * FROM @tbl2Child AS c
            WHERE p.ID = c.ParentID
            FOR XML PATH('allocation_row'), TYPE
    ) 
    FROM @tbl2 AS p
    FOR XML PATH('tradeTicket'), TYPE
)
FROM @tbl1
FOR XML PATH(''), TYPE, ROOT('tradeTickets');

输出

<tradeTickets>
  <tradeTicket>
    <ID>8</ID>
    <Manager>DOYLE</Manager>
    <allocation_row>
      <accountNumber>F11</accountNumber>
      <ParentID>8</ParentID>
      <unitPrice>100.00</unitPrice>
    </allocation_row>
    <allocation_row>
      <accountNumber>F22</accountNumber>
      <ParentID>8</ParentID>
      <unitPrice>200.00</unitPrice>
    </allocation_row>
  </tradeTicket>
  <tradeTicket>
    <ID>9</ID>
    <Manager>XYZ</Manager>
    <allocation_row>
      <accountNumber>F70</accountNumber>
      <ParentID>9</ParentID>
      <unitPrice>770.00</unitPrice>
    </allocation_row>
  </tradeTicket>
  <tradeTicket>
    <ID>8779555</ID>
    <Manager>TTT</Manager>
    <allocation_row>
      <accountNumber>255</accountNumber>
      <ParentID>8779555</ParentID>
      <unitPrice>500.00</unitPrice>
    </allocation_row>
  </tradeTicket>
  <tradeTicket>
    <ID>8779631</ID>
    <Manager>MCM</Manager>
    <allocation_row>
      <accountNumber>292</accountNumber>
      <ParentID>8779631</ParentID>
      <unitPrice>300.00</unitPrice>
    </allocation_row>
  </tradeTicket>
</tradeTickets>

【讨论】:

  • 谢谢。不幸的是,我们的表没有您表上的依赖项 ParentID。使用我的表格,我创建了一些与我的预期结果相似的东西。唯一的问题是 ID、SystemSource、Manager、accountNumber、unitPrice 都不是自己的元素。我已经用这个更新了我原来的帖子。
  • 在您的 OP 中您两次提到表之间存在一对多关系。在 DB 层面是如何实现的?
  • 对于每个 myTbl id,myAllocation 表中可能有 0 到多个 trade_ticket_id。对于每个 ABC_myTbl id,ABC_myAllocation 表中可能有 0 到多个 trade_ticket_id。因此,这里的 LEFT JOIN: ....FROM myTbl AS trTicket LEFT JOIN myAllocation AS allocationRow ON allocationRow.trade_ticket_id=trTicket.id
  • 好的。所以尝试使用我展示的方法,并使用WHERE 子句而不是LEFT OUTER JOIN 连接。
  • 嗨,@"Yitzhak Khabinsky" 在您的示例中,如果 tbl1 或 tbl2 中有多个 IDS,例如:INSERT INTO tbl1 (ID, Manager) VALUES (9, 'XYZ') ,XML 将所有 ID 放在同一个 下。我需要每个 ID 在每个自己的 中。我怎样才能做到这一点 ?我在stackoverflow.com/questions/61082358/… 发布了这个问题
猜你喜欢
  • 1970-01-01
  • 2013-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-10
  • 1970-01-01
  • 2021-09-02
  • 1970-01-01
相关资源
最近更新 更多