如何从1 sql中的XMLTYPE字段多个聚合?

时间:2012-03-13 08:54:41

标签: sql xml database oracle

Belows是存储在数据类型为XMLTYPE的字段调用xmldoc中的xml数据,并且模式存储在每个记录中。

xmldoc字段的第一行(记录)应为:

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

并且xmldoc字段的第二行应为:

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

并且下面的xml数据也被修改为上面的示例(每个数据存储在xmldoc字段的行记录中并嵌入'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>

现在,我使用这个sql:

SELECT X.year, x.month, sum(x.data) as sumMonth
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
group by x.year, x.month

按x.year,x.month

排序

我可以从这个sql得到每年每个月的“数据”总和,我想知道的问题是如何在sumMonth列之后显示每年的总和,只是修改这个sql但是不要使用两个或多个sql 来同时获得月份和年份的聚合。

输出可能是这样的:

year month  sumMonth sumYear
2009  Jan    3840     10680
2009  Feb    6840     10680
2010  Jan    3843     10686
2010  Feb    6843     10686
谢谢大家给了我答案:)

1 个答案:

答案 0 :(得分:0)

您可以使用analytic function

SELECT v.YEAR, v.MONTH, v.sumMonth, 
       SUM(v.sumMonth) over(PARTITION BY v.YEAR) sumYear
  FROM (SELECT X.YEAR, x.MONTH, SUM(x.data) AS sumMonth
           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
          GROUP BY x.YEAR, x.MONTH) v