聚合数据库中XMLTYPE的值

时间:2012-03-12 14:21:49

标签: sql xml oracle relational-database

我在XMLTYPE中的每一行字段中都存储了XML数据, XML字段的第一行应该是:

<cdata>
<r> <year>2009</year>
<month>Jan</month>
<day>1</day>
<data>1180</data>
</r>
</cdata>

,XML字段的第二行应为:

<cdata>
<r>
<year>2009</year>
<month>Jan</month>
<day>2</day>
<data>1280</data>
</r>
</cdata>

以及下面的代码也被修改为上面的例子(每个数据存储在一行并嵌入'cdata'根元素。

<r>
<year>2009</year>
<month>Jan</month>
<day>3</day>
<data>1380</data>
</r>
<r>
<year>2009</year>
<month>Feb</month>
<day>1</day>
<data>2180</data>
</r>
<r>
<year>2009</year>
<month>Feb</month>
<day>2</day>
<data>2280</data>
</r>
<r>
<year>2009</year>
<month>Feb</month>
<day>3</day>
<data>2380</data>
</r>
<r>
<year>2010</year>
<month>Jan</month>
<day>1</day>
<data>1181</data>
</r>
<r>
<year>2010</year>
<month>Jan</month>
<day>2</day>
<data>1281</data>
</r>
<r>
<year>2010</year>
<month>Jan</month>
<day>3</day>
<data>1381</data>
</r>
<r>
<year>2010</year>
<month>Feb</month>
<day>1</day>
<data>2181</data>
</r>
<r>
<year>2010</year>
<month>Feb</month>
<day>2</day>
<data>2281</data>
</r>
<r>
<year>2010</year>
<month>Feb</month>
<day>3</day>
<data>2381</data>
</r>
</cdata>

现在,我使用这个sql:

SELECT X.* 
FROM xmltest, 
XMLTABLE ('$d/cdata/r' passing xmldoc as "d" 
   COLUMNS 
  year integer path 'year',
  month varchar(3) path 'month',
  day varchar(2) path 'day',
  data float path 'data'
  ) AS X

我可以检索记录中的值, 问题是如何汇总2009年/ 1月份的“数据”元素总数? 什么是我可以用来汇总2009年全年“数据”元素的代码?

2 个答案:

答案 0 :(得分:2)

一旦您确定了如何查询XML,就可以与standard SQL aggregate functions进行汇总:

SELECT X.year, x.month, sum(data)
FROM (select xmltype(xmldoc) xmldoc from data), 
XMLTABLE ('$d/cdata/r' passing xmldoc as "d" 
   COLUMNS 
  year integer path 'year',
  month varchar(3) path 'month',
  day varchar(2) path 'day',
  data float path 'data'
  ) AS X
group by x.year, x.month

答案 1 :(得分:0)

具体取决于您可以做什么输出,以获得2009年1月的总数

SELECT SUM( x.data )
  FROM xmltest, 
  XMLTABLE ('$d/cdata/r' passing xmldoc as "d" 
   COLUMNS 
  year integer path 'year',
  month varchar(3) path 'month',
  day varchar(2) path 'day',
  data float path 'data'
  ) AS X
 WHERE x.year = 2009
   AND x.month = 'Jan'

这将获得2009年全年的总数

SELECT SUM( x.data )
  FROM xmltest, 
  XMLTABLE ('$d/cdata/r' passing xmldoc as "d" 
   COLUMNS 
  year integer path 'year',
  month varchar(3) path 'month',
  day varchar(2) path 'day',
  data float path 'data'
  ) AS X
 WHERE x.year = 2009

使用您的样本数据并假设该表定义为

CREATE TABLE xmltest (
  xmldoc XMLTYPE 
);

产生这样的输出

SQL> ed
Wrote file afiedt.buf

  1  SELECT SUM( x.data )
  2    FROM xmltest,
  3    XMLTABLE ('$d/cdata/r' passing xmldoc as "d"
  4     COLUMNS
  5    year integer path 'year',
  6    month varchar(3) path 'month',
  7    day varchar(2) path 'day',
  8    data float path 'data'
  9    ) AS X
 10*  WHERE x.year = 2009
SQL> /

SUM(X.DATA)
-----------
      10680

SQL> SELECT SUM( x.data )
  2    FROM xmltest,
  3    XMLTABLE ('$d/cdata/r' passing xmldoc as "d"
  4     COLUMNS
  5    year integer path 'year',
  6    month varchar(3) path 'month',
  7    day varchar(2) path 'day',
  8    data float path 'data'
  9    ) AS X
 10   WHERE x.year = 2009
 11     AND x.month = 'Jan';

SUM(X.DATA)
-----------
       3840