XMLSEQUENCE - ignore parent if child contains "void"

时间:2017-05-16 09:19:37

标签: sql xml oracle

I am trying to report on all card transactions that contain a certain type of Tender Entry Method.

A three column report with the Register Number, Count of Transactions, Total Value.

The problem I have is a transaction can contain multiple "TokenisedCardTenderItem" and the below query gets these and Counts and Totals correctly; however....

A "TokenisedCardTenderItem" can also include a "VoidValue" child meaning for some reason that particular tender was cancelled. The query below is also counting and adding the value of these.

My question is how can I exclude all "TokenisedCardTenderItem" that have a "VoidValue" child, but keep counting "TokenisedCardTenderItem" that do not.

SELECT 
terminal_number 
,count (Extractvalue(c.column_value, 'TokenisedCardTenderItem/PreformattedTextLines/PreformattedTextLine[7]') )   as con
,count (Extractvalue(c.column_value, 'TokenisedCardTenderItem/NetValue') ) / 100   as val
FROM baskets b ,
TABLE(xmlsequence(extract(xmltype(b.xml),'/POSBasket/TokenisedCardTenderItem'))) c  
where DATE_CREATED>TO_DATE('2017-05-12 00:00:00','yyyy-MM-dd HH24:mi:ss')
AND store_id = 9999
AND terminal_number = 982
and EXISTSNODE(xmltype.createxml(xml), '/POSBasket/TokenisedCardTenderItem/PreformattedTextLines[PreformattedTextLine="CONTACTLESS"]') = 1
GROUP BY terminal_number, 
         Extractvalue(c.column_value, 'PreformattedTextLines/PreformattedTextLine[7]')  
order by 1,2

Cut down version of xml below:

            <POSBasket>
                <TokenisedCardTenderItem>
                    <LineNumber>3</LineNumber>
                    <NetValue>-1</NetValue>
                    <VoidValue>1</VoidValue>
                    <EffectiveNetValue>-1</EffectiveNetValue>
                </TokenisedCardTenderItem>
                <VoidItem>
                    <LineNumber>4</LineNumber>
                    <NetValue>1</NetValue>
                    <EffectiveNetValue>1</EffectiveNetValue>
                    <VoidedLineNumber>3</VoidedLineNumber>
                </VoidItem>
                <TokenisedCardTenderItem>
                    <LineNumber>5</LineNumber>
                    <NetValue>2</NetValue>
                    <EffectiveNetValue>2</EffectiveNetValue>
                    <PreformattedTextLines>
                        <PreformattedTextVoucherType>1</PreformattedTextVoucherType>
                        <PreformattedTextLine></PreformattedTextLine>
                        <PreformattedTextLine></PreformattedTextLine>
                        <PreformattedTextLine></PreformattedTextLine>
                        <PreformattedTextLine></PreformattedTextLine>
                        <PreformattedTextLine></PreformattedTextLine>
                        <PreformattedTextLine></PreformattedTextLine>
                        <PreformattedTextLine>CONTACTLESS</PreformattedTextLine>
                        <PreformattedTextLine>SALE</PreformattedTextLine>
                        <PreformattedTextLine>TOTAL: GBP0.02</PreformattedTextLine>
                    </PreformattedTextLines>
                </TokenisedCardTenderItem>
                <TokenisedCardTenderItem>
                    <LineNumber>6</LineNumber>
                    <NetValue>3</NetValue>
                    <EffectiveNetValue>3</EffectiveNetValue>
                    <PreformattedTextLines>
                        <PreformattedTextVoucherType>1</PreformattedTextVoucherType>
                        <PreformattedTextLine></PreformattedTextLine>
                        <PreformattedTextLine></PreformattedTextLine>
                        <PreformattedTextLine></PreformattedTextLine>
                        <PreformattedTextLine></PreformattedTextLine>
                        <PreformattedTextLine></PreformattedTextLine>
                        <PreformattedTextLine></PreformattedTextLine>
                        <PreformattedTextLine>CONTACTLESS</PreformattedTextLine>
                        <PreformattedTextLine>SALE</PreformattedTextLine>
                        <PreformattedTextLine>TOTAL: GBP0.03</PreformattedTextLine>
                    </PreformattedTextLines>
                </TokenisedCardTenderItem>
            </POSBasket>

From this I would hope to see :

   Terminal  Con    Val
     982     2      0.05

But i get the below as the voided netvalue is being included.

   Terminal  Con    Val
     982      2     0.06

1 个答案:

答案 0 :(得分:0)

我认为这就是你要找的东西

 SQL> with MY_TABLE as
   2  (
   3    select 982 as TERMINAL, XMLTYPE(
   4  '          <POSBasket>
   5                  <TokenisedCardTenderItem>
   6                      <LineNumber>3</LineNumber>
   7                      <NetValue>-1</NetValue>
   8                      <VoidValue>1</VoidValue>
   9                      <EffectiveNetValue>-1</EffectiveNetValue>
  10                  </TokenisedCardTenderItem>
  11                  <VoidItem>
  12                      <LineNumber>4</LineNumber>
  13                      <NetValue>1</NetValue>
  14                      <EffectiveNetValue>1</EffectiveNetValue>
  15                      <VoidedLineNumber>3</VoidedLineNumber>
  16                  </VoidItem>
  17                  <TokenisedCardTenderItem>
  18                      <LineNumber>5</LineNumber>
  19                      <NetValue>2</NetValue>
  20                      <EffectiveNetValue>2</EffectiveNetValue>
  21                      <PreformattedTextLines>
  22                          <PreformattedTextVoucherType>1</PreformattedTextVoucherType>
  23                          <PreformattedTextLine></PreformattedTextLine>
  24                          <PreformattedTextLine></PreformattedTextLine>
  25                          <PreformattedTextLine></PreformattedTextLine>
  26                          <PreformattedTextLine></PreformattedTextLine>
  27                          <PreformattedTextLine></PreformattedTextLine>
  28                          <PreformattedTextLine></PreformattedTextLine>
  29                          <PreformattedTextLine>CONTACTLESS</PreformattedTextLine>
  30                          <PreformattedTextLine>SALE</PreformattedTextLine>
  31                          <PreformattedTextLine>TOTAL: GBP0.02</PreformattedTextLine>
  32                      </PreformattedTextLines>
  33                  </TokenisedCardTenderItem>
  34                  <TokenisedCardTenderItem>
  35                      <LineNumber>6</LineNumber>
  36                      <NetValue>3</NetValue>
  37                      <EffectiveNetValue>3</EffectiveNetValue>
  38                      <PreformattedTextLines>
  39                          <PreformattedTextVoucherType>1</PreformattedTextVoucherType>
  40                          <PreformattedTextLine></PreformattedTextLine>
  41                          <PreformattedTextLine></PreformattedTextLine>
  42                          <PreformattedTextLine></PreformattedTextLine>
  43                          <PreformattedTextLine></PreformattedTextLine>
  44                          <PreformattedTextLine></PreformattedTextLine>
  45                          <PreformattedTextLine></PreformattedTextLine>
  46                          <PreformattedTextLine>CONTACTLESS</PreformattedTextLine>
  47                          <PreformattedTextLine>SALE</PreformattedTextLine>
  48                          <PreformattedTextLine>TOTAL: GBP0.03</PreformattedTextLine>
  49                      </PreformattedTextLines>
  50                  </TokenisedCardTenderItem>
  51              </POSBasket>') as XML_DOC
  52    from DUAL
  53  )
  54  select TERMINAL, CNT, SUM(VAL) / 100
  55    from MY_TABLE,
  56         XMLTABLE(
  57           '/POSBasket'
  58           passing XML_DOC
  59           columns
  60             CNT NUMBER(2) PATH 'count(/POSBasket/TokenisedCardTenderItem/PreformattedTextLines/PreformattedTextLine[
 7])',
  61             TCTI_XML XMLTYPE PATH '/POSBasket/TokenisedCardTenderItem[not(VoidValue)]'
  62         ),
  63         XMLTABLE(
  64           'TokenisedCardTenderItem'
  65           passing TCTI_XML
  66           COLUMNS
  67           VAL NUMBER(2) PATH 'NetValue'
  68         )
  69   group by TERMINAL, CNT
  70  /

   TERMINAL        CNT SUM(VAL)/100
 ---------- ---------- ------------
        982          2          .05

 SQL>
 SQL>
 SQL>