Как совместить два FOR XML AUTO в 1 XML? - PullRequest
0 голосов
/ 27 марта 2020

Мы используем SQL Server 2012.

  • Таблица myTbl имеет отношение один-ко-многим к таблице myAllocation
  • Таблица ABC_myTbl имеет единицу к много связей с таблицей ABC_myAllocation

Приведенный ниже запрос объединяет 2 FOR XML AUTO в 1 XML, но проблема в том, что ID, SystemSource, Manager включены в элемент TradeTicket, а не в их own и accountManager, unitPrice включены в elementRow элемента, а не самостоятельно.

Спасибо

        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 Ответ

1 голос
/ 27 марта 2020

Я не дождался вашего 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>
...