在从数据库select检索xmltype时需要帮助

时间:2018-09-24 16:42:52

标签: sql database oracle

我有下面的数据库表0xFF80,其中有5列:

CASH

其中的收银机号码是可以链接多个CASE的收银机,并且每个CASE可以附加一个以上的BAG和Type。

我要实现的目标如下:

REGISTER    DATE    CASE    BAG TYPE
1234    24-SEP-18   1123    112 A
1234    24-SEP-18   1124    113 S
1234    24-SEP-18   1123    116 S
1234    24-SEP-18   1124    117 A
7895    24-SEP-18   2568    119 A
7895    24-SEP-18   2568    118 S

能否请您提供一些指示,如何在Oracle数据库选择查询中实现此目标?我不想创建存储过程,也不想在选择查询中实现这一点。

1 个答案:

答案 0 :(得分:0)

首先,请不要使用Oracle保留字(“ date”,“ case”,“ type”)作为列名!用双引号将每个列名都变得烦人。

因此,这是一个非常复杂的场景。您尝试在同一张表上进行3种汇总。

此外,Oracle的XML函数使您无法在查询中即时构造XML。我知道在XML层次结构的同一级别上混合列(xmlelement)和行(xmlagg)数据的唯一方法是使用xmlelement构造函数将它们连接起来。

此外,我还假设您的“ / ROOT / REGISTERS / DETAILS / BAG”标签是错字,而您的意思是“ CASE”。

但是我认为这就是您要的。

create table cash (register number, "DATE" date, "CASE" number, bag number, "TYPE" varchar2(1));
insert into cash values (1234, to_date('09/24/2018', 'mm/dd/yyyy'), 1123, 112, 'A');
insert into cash values (1234, to_date('09/24/2018', 'mm/dd/yyyy'), 1124, 113, 'S');
insert into cash values (1234, to_date('09/24/2018', 'mm/dd/yyyy'), 1123, 116, 'S');
insert into cash values (1234, to_date('09/24/2018', 'mm/dd/yyyy'), 1124, 117, 'A');
insert into cash values (7895, to_date('09/24/2018', 'mm/dd/yyyy'), 2568, 119, 'A');
insert into cash values (7895, to_date('09/24/2018', 'mm/dd/yyyy'), 2568, 118, 'S');

select xmlelement("ROOT",
        xmlagg(xmlelement("REGISTERS",
                xmlelement("REGISTER", t1.register), 
                xmlelement("DATE", t1."DATE"),
                (select xmlagg(xmlelement("DETAILS",
                                 xmlelement("CASE", t2."CASE"),
                                 (select xmlagg(xmlelement("DETAIL",
                                                xmlforest(t3.bag, t3."TYPE"))
                                                )
                                    from (select bag, "TYPE" from cash 
                                          where cash."REGISTER" = t2."REGISTER" and cash."DATE" = t2."DATE"
                                            and cash."CASE" = t2."CASE") t3)
                               ))
                       from (select distinct register, "DATE", "CASE" from cash
                             where cash."REGISTER" = t1."REGISTER" and cash."DATE" = t1."DATE") t2
                       )
                )  
        )
    ) as xml_data
from (select distinct register, "DATE" from cash) t1
;

输出:

<ROOT>
   <REGISTERS>
      <REGISTER>1234</REGISTER>
      <DATE>2018-09-24</DATE>
      <DETAILS>
         <CASE>1123</CASE>
         <DETAIL>
            <BAG>112</BAG>
            <TYPE>A</TYPE>
         </DETAIL>
         <DETAIL>
            <BAG>116</BAG>
            <TYPE>S</TYPE>
         </DETAIL>
      </DETAILS>
      <DETAILS>
         <CASE>1124</CASE>
         <DETAIL>
            <BAG>113</BAG>
            <TYPE>S</TYPE>
         </DETAIL>
         <DETAIL>
            <BAG>117</BAG>
            <TYPE>A</TYPE>
         </DETAIL>
      </DETAILS>
   </REGISTERS>
   <REGISTERS>
      <REGISTER>7895</REGISTER>
      <DATE>2018-09-24</DATE>
      <DETAILS>
         <CASE>2568</CASE>
         <DETAIL>
            <BAG>119</BAG>
            <TYPE>A</TYPE>
         </DETAIL>
         <DETAIL>
            <BAG>118</BAG>
            <TYPE>S</TYPE>
         </DETAIL>
      </DETAILS>
   </REGISTERS>
</ROOT>