Агрегировать значения из XMLTYPE в базе данных - PullRequest
1 голос
/ 12 марта 2012

У меня есть данные XML, хранящиеся в каждой строке поля в XMLTYPE, первая строка поля 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

Я могу получить значение в записи, и вопрос в том, как я могу агрегировать итоговое значение элемента «data» в 2009 / январе? И какой код я могу использовать для агрегированияэлемент данных за весь 2009 год?

Ответы [ 2 ]

2 голосов
/ 12 марта 2012

Как только вы научитесь запрашивать XML, вы можете агрегировать с стандартными функциями агрегирования SQL :

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
0 голосов
/ 12 марта 2012

В зависимости от того, что именно вы можете сделать, вы можете сделать что-то вроде этого, чтобы получить сумму в январе 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
   AND x.month = 'Jan'

и это, чтобы получить сумму за весь 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
...