Upload
philomena-white
View
241
Download
0
Tags:
Embed Size (px)
Citation preview
SQL AggregationSQL Aggregation Oracle and ANSI Standard SQLOracle and ANSI Standard SQLLecture 9Lecture 9
SQL AggregationSQL Aggregation
Copyright 2006Page 2
SQL AggregationSQL AggregationCOUNT()COUNT() Function Function
COUNT({ * | [DISTINCT|ALL] | expression })COUNT({ * | [DISTINCT|ALL] | expression })
Copyright 2006Page 3
SQL AggregationSQL AggregationCOUNT()COUNT() Function Function
COUNT()COUNT() function functionThe The COUNT()COUNT() function counts a set of things function counts a set of things
based on it being the only column value based on it being the only column value selected:selected: Returning only one column and row with the total Returning only one column and row with the total
number of rows found.number of rows found.The The COUNT()COUNT() function counts a set of things function counts a set of things
based on a criteria specified in a based on a criteria specified in a GROUP BYGROUP BY clause and more than one column is selected:clause and more than one column is selected: Returning more than one row when there is more Returning more than one row when there is more
than one row of the grouping column, andthan one row of the grouping column, and Returning the count of how many times the Returning the count of how many times the
grouping columns occur in the set.grouping columns occur in the set.
Copyright 2006Page 4
SQL AggregationSQL AggregationCOUNT()COUNT() Function Function
COUNT(*)COUNT(*) This approach counts all rows including those with NULL values.This approach counts all rows including those with NULL values.
COUNT(*)COUNT(*) with a with a GROUP BYGROUP BY col_name col_name This approach counts all rows uniquely identified by the column This approach counts all rows uniquely identified by the column
name, substituting 1 for all rows identified as unique provided name, substituting 1 for all rows identified as unique provided there is only one row containing unique column values.there is only one row containing unique column values.
COUNT(col_name)COUNT(col_name) This approach counts all rows excluding those rows that contain a This approach counts all rows excluding those rows that contain a
NULL value for the designated column name.NULL value for the designated column name.
COUNT(col_name)COUNT(col_name) with a with a GROUP BYGROUP BY col_namecol_name This approach counts all rows including rows that contain a This approach counts all rows including rows that contain a NULLNULL
value, substituting 1 for not null values and 0 for null values value, substituting 1 for not null values and 0 for null values provided there is only one row containing unique column values.provided there is only one row containing unique column values.
Copyright 2006Page 5
SQL AggregationSQL AggregationCOUNT()COUNT() Function: Counts a row Function: Counts a row
SELECT COUNT(*)SELECT COUNT(*)
FROM a_table a;FROM a_table a;
Copyright 2006Page 6
SQL AggregationSQL AggregationCOUNT()COUNT() Function: Counts Function: Counts
valuesvalues
SELECT COUNT(a.column_name)SELECT COUNT(a.column_name)
FROM a_table a;FROM a_table a;
Copyright 2006Page 7
SQL AggregationSQL AggregationCOUNT()COUNT() Function: Counts values Function: Counts values
SELECT COUNT(value_list)SELECT COUNT(value_list)
FROM counting;FROM counting;
Contains two copies of the Contains two copies of the single digit ordinal numbers, single digit ordinal numbers, and two null values.and two null values.
Selecting only Selecting only COUNT(*)COUNT(*) from from the table returns 22 rows.the table returns 22 rows.
COUNT(VALUE_LIST)COUNT(VALUE_LIST)
----------------------------------
2020
1 row selected.1 row selected.
Copyright 2006Page
8
SQL AggregationSQL AggregationCOUNT()COUNT() Function: Counts Function: Counts
valuesvalues
SELECT a.column_name1SELECT a.column_name1
, COUNT(a.column_name), COUNT(a.column_name)
FROM a_table aFROM a_table a
GROUP BY a.column_name2;GROUP BY a.column_name2;
Copyright 2006Page 9
SQL AggregationSQL AggregationCOUNT()COUNT() Function: Counts values Function: Counts values
SELECT value_listSELECT value_list
, COUNT(value_list), COUNT(value_list)
FROM countingFROM counting
GROUP BY value_list;GROUP BY value_list;
Contains two copies of the Contains two copies of the single digit ordinal numbers, single digit ordinal numbers, and two null values.and two null values.
Selecting only Selecting only COUNT(*)COUNT(*) from from the table returns 22 rows.the table returns 22 rows.
VALUE_LIST COUNT(VALUE_LIST)VALUE_LIST COUNT(VALUE_LIST)---------- --------------------------- ----------------- 0 20 2 1 21 2 2 22 2 3 23 2 4 24 2 5 25 2 6 26 2 7 27 2 8 28 2 9 29 2 00
11 rows selected.11 rows selected.
Copyright 2006Page10
SQL AggregationSQL AggregationSUM()SUM() Function Function
SUM({ [DISTINCT|ALL] | value })SUM({ [DISTINCT|ALL] | value })
SUM({ [DISTINCT|ALL] | formula })SUM({ [DISTINCT|ALL] | formula })
Copyright 2006Page 11
SQL AggregationSQL AggregationSUM()SUM() Function Function
SUM()SUM() function functionThe The SUM()SUM() function sums a set of things function sums a set of things
based on it being the only column value based on it being the only column value selected:selected: Returning only one column and row with the sum of Returning only one column and row with the sum of
a set of column values.a set of column values.
The The SUM()SUM() function sums a set of things function sums a set of things based on a criteria specified in a based on a criteria specified in a GROUP BYGROUP BY clause and more than one column is selected:clause and more than one column is selected: Returning more than one row when there is more Returning more than one row when there is more
than one row of the grouping column, andthan one row of the grouping column, and Returning the count of how many times the Returning the count of how many times the
grouping columns occur in the set.grouping columns occur in the set. Copyright 2006Page 12
SQL AggregationSQL AggregationSUM()SUM() Function Function
The The SUM()SUM() function requires a function requires a NUMBERNUMBER data data type or subtype.type or subtype.
SUM(column_value)SUM(column_value) This approach adds all rows values for a column This approach adds all rows values for a column
name.name.
SUM(formula returing value)SUM(formula returing value) This approach adds all rows based on the formula.This approach adds all rows based on the formula.
SUM()SUM() functions can be used in: functions can be used in: The The SELECTSELECT and and HAVINGHAVING clauses. clauses.
Copyright 2006Page 13
SQL AggregationSQL AggregationSUM()SUM() Function: Sums a row Function: Sums a row
SELECT SUM(a.column_name)SELECT SUM(a.column_name)
FROM a_table a;FROM a_table a;
Copyright 2006Page 14
SELECT SUM(value_list)SELECT SUM(value_list)
FROM counting;FROM counting;
Contains two copies of the Contains two copies of the single digit ordinal single digit ordinal numbers, and two null numbers, and two null values.values.
SUM(VALUE_LIST)SUM(VALUE_LIST)
------------------------------
9090
1 row selected.1 row selected.
Copyright 2006Page 15
SQL AggregationSQL AggregationSUM()SUM() Function: Sums values Function: Sums values
SQL AggregationSQL AggregationSUM()SUM() Function: Sums a row Function: Sums a row
SELECT a.column_name1SELECT a.column_name1
, SUM(a.column_name2), SUM(a.column_name2)
FROM a_table aFROM a_table a
GROUP BY a.column_name1;GROUP BY a.column_name1;
Copyright 2006Page 16
SELECT value_listSELECT value_list
, SUM(value_list), SUM(value_list)
FROM countingFROM counting
GROUP BY value_list;GROUP BY value_list;
Contains two copies of the Contains two copies of the single digit ordinal numbers, single digit ordinal numbers, and two null values.and two null values.
Grouping by the Grouping by the VALUE_LISTVALUE_LIST value, the sum is twice the value, the sum is twice the value in the column.value in the column.
VALUE_LIST SUM(VALUE_LIST)VALUE_LIST SUM(VALUE_LIST)---------- ------------------------- --------------- 0 00 0 1 21 2 2 42 4 3 63 6 4 84 8 5 105 10 6 126 12 7 147 14 8 168 16 9 189 18
11 rows selected.11 rows selected.
Copyright 2006Page 17
SQL AggregationSQL AggregationSUM()SUM() Function: Sums values Function: Sums values
SQL AggregationSQL AggregationAVG()AVG() Function Function
AVG({ [DISTINCT|ALL] | value })AVG({ [DISTINCT|ALL] | value })
AVG({ [DISTINCT|ALL] | formula })AVG({ [DISTINCT|ALL] | formula })
Copyright 2006Page 18
SQL AggregationSQL AggregationAVG()AVG() Function Function
The The AVG()AVG() function averages a set of things and function averages a set of things and returns only one row when it is the only return returns only one row when it is the only return value in a value in a SELECTSELECT clause. clause.
The The AVG()AVG() function averages a set of things function averages a set of things based on a criteria specified in a based on a criteria specified in a GROUP BYGROUP BY clause and returns more than one row – the clause and returns more than one row – the grouping attribute and the average of their grouping attribute and the average of their occurrences in the set.occurrences in the set.
Copyright 2006Page 19
SQL AggregationSQL AggregationAVG()AVG() Function Function
The The AVG()AVG() function requires a function requires a NUMBERNUMBER data data type or subtype.type or subtype.
AVG(column_value)AVG(column_value) This approach averages all rows values for a This approach averages all rows values for a
column name.column name.
AVG(formula returing value)AVG(formula returing value) This approach averages all rows based on the This approach averages all rows based on the
formula.formula.
AVG()AVG() functions can be used in: functions can be used in: The The SELECTSELECT and and HAVINGHAVING clauses. clauses.
Copyright 2006Page 20
SQL AggregationSQL AggregationAVG()AVG() Function: Average a column Function: Average a column
valuevalue
SELECT AVG(a.column_name)SELECT AVG(a.column_name)
FROM a_table a;FROM a_table a;
Copyright 2006Page 21
SELECT AVG(value_list)SELECT AVG(value_list)
FROM counting;FROM counting;
Contains two copies of the Contains two copies of the single digit ordinal single digit ordinal numbers, and two null numbers, and two null values.values.
AVG(VALUE_LIST)AVG(VALUE_LIST)
------------------------------
4.54.5
1 row selected.1 row selected.
Copyright 2006Page 22
SQL AggregationSQL AggregationAVG()AVG() Function: Average a column Function: Average a column
valuevalue
SQL AggregationSQL Aggregation AVG()AVG() Function: Average a column Function: Average a column
valuesvalues
SELECT a.column_name1SELECT a.column_name1
, AVG(a.column_name2), AVG(a.column_name2)
FROM a_table aFROM a_table a
GROUP BY a.column_name1;GROUP BY a.column_name1;
Copyright 2006Page 23
SQL AggregationSQL Aggregation AVG()AVG() Function: Average a column Function: Average a column
valuesvalues
SELECT value_listSELECT value_list
, AVG(value_list), AVG(value_list)
FROM countingFROM counting
GROUP BY value_list;GROUP BY value_list;
Contains two copies of the Contains two copies of the single digit ordinal numbers, single digit ordinal numbers, and two null values.and two null values.
Grouping by the Grouping by the VALUE_LISTVALUE_LIST value, the average is the value, the average is the value in the column.value in the column.
VALUE_LIST AVG(VALUE_LIST)VALUE_LIST AVG(VALUE_LIST)
---------- ------------------------- ---------------
0 00 0
1 11 1
2 22 2
3 33 3
4 44 4
5 55 5
6 66 6
7 77 7
8 88 8
9 99 9
11 rows selected.11 rows selected.
Copyright 2006Page 24
SQL AggregationSQL AggregationMAX()MAX() Function Function
MAX({ [DISTINCT|ALL] | expression })MAX({ [DISTINCT|ALL] | expression })
OVER (PARTITION BY expression)OVER (PARTITION BY expression)
Copyright 2006Page 25
SQL AggregationSQL AggregationMAX()MAX() Function Function
The The MAX()MAX() function: function: Requires a scalar type or subtypeRequires a scalar type or subtype Can use an analytical function, like Can use an analytical function, like PARTITION BYPARTITION BY
MAX(column_name)MAX(column_name) This approach finds the highest value of an This approach finds the highest value of an
expression, ASCII values are used for strings.expression, ASCII values are used for strings. NULLNULL are sorted last in ascending order and first in are sorted last in ascending order and first in
descending order.descending order.
MAX(column_name)MAX(column_name)OVER (PARTITION BY column_name)OVER (PARTITION BY column_name) This approach finds the highest value of an This approach finds the highest value of an
expression based on its relationship in the result set expression based on its relationship in the result set to the partitioning column, ASCII values are used for to the partitioning column, ASCII values are used for strings.strings.
NULLNULL are sorted last in ascending order and first in are sorted last in ascending order and first in descending order.descending order.
Copyright 2006Page 26
SQL AggregationSQL AggregationMAX()MAX() Function: Finds maximum Function: Finds maximum
valuevalue
SELECT MAX(a.column_name)SELECT MAX(a.column_name)
FROM a_table a;FROM a_table a;
Copyright 2006Page 27
SQL AggregationSQL AggregationMAX()MAX() Function: Finds maximum Function: Finds maximum
valuevalue
SELECT MAX(value_list)SELECT MAX(value_list)
FROM counting;FROM counting;
Contains two copies of the Contains two copies of the single digit ordinal numbers, single digit ordinal numbers, and two null values.and two null values.
It returns the highest It returns the highest number without any number without any grouping or partitioning.grouping or partitioning.
MAX(VALUE_LIST)MAX(VALUE_LIST)
------------------------------
99
1 row selected.1 row selected.
Copyright 2006Page 28
SQL AggregationSQL AggregationMAX()MAX() Function: Finds maximum Function: Finds maximum
valuevalue
SELECT MAX(a.column_name1)SELECT MAX(a.column_name1)
OVER (PARTITION BY a.column_name2)OVER (PARTITION BY a.column_name2)
FROM a_table a;FROM a_table a;
Copyright 2006Page 29
SQL AggregationSQL AggregationMAX()MAX() Function: Finds maximum Function: Finds maximum
valuevalue
SELECT a.column_name1SELECT a.column_name1
, MAX(a.column_name2), MAX(a.column_name2)
FROM a_table aFROM a_table a
GROUP BY a.column_name1;GROUP BY a.column_name1;
Copyright 2006Page 30
SQL AggregationSQL AggregationMAX()MAX() Function: Finds Maximum Value Function: Finds Maximum Value
SELECT value_listSELECT value_list
, MAX(value_list), MAX(value_list)
FROM countingFROM counting
GROUP BY value_list;GROUP BY value_list;
Contains two copies of the Contains two copies of the single digit ordinal numbers, single digit ordinal numbers, and two null values.and two null values.
Grouping by the Grouping by the VALUE_LISTVALUE_LIST value, the maximum is the value, the maximum is the value in the column.value in the column.
VALUE_LIST MAX(VALUE_LIST)VALUE_LIST MAX(VALUE_LIST)
---------- ------------------------- ---------------
0 00 0
1 11 1
2 22 2
3 33 3
4 44 4
5 55 5
6 66 6
7 77 7
8 88 8
9 99 9
11 rows selected.11 rows selected.
Copyright 2006Page 31
SQL AggregationSQL AggregationMAX()MAX() Function: Finds Function: Finds
maximum valuemaximum value
SELECT DISTINCTSELECT DISTINCT
a.column_name1a.column_name1
, MAX(a.column_name2), MAX(a.column_name2)
OVER (PARTITION BY a.column_name1)OVER (PARTITION BY a.column_name1)
FROM a_table a;FROM a_table a;
Copyright 2006Page 32
SQL AggregationSQL AggregationMAX()MAX() Function: Finds maximum Function: Finds maximum
valuevalue
SELECT DISTINCTSELECT DISTINCT
value_namevalue_name
, MAX(value_list), MAX(value_list)
OVEROVER
(PARTITION BY value_name)(PARTITION BY value_name)
FROM counting;FROM counting;
Contains two copies of the Contains two copies of the single digit ordinal numbers, single digit ordinal numbers, and two null values.and two null values.
The The OVEROVER clause disallows clause disallows the use of the the use of the GROUP BYGROUP BY clause and a clause and a DISTINCTDISTINCT provides meaningful results.provides meaningful results.
VALUE_NAME MAX(VALUE_LIST)VALUE_NAME MAX(VALUE_LIST)
---------- ------------------------- ---------------
1ST Set 91ST Set 9
2ND Set 92ND Set 9
2 rows selected.2 rows selected.
Copyright 2006Page 33
SQL AggregationSQL AggregationMIN()MIN() Function Function
MIN({ [DISTINCT|ALL] | expression })MIN({ [DISTINCT|ALL] | expression })
OVER (PARTITION BY expression)OVER (PARTITION BY expression)
Copyright 2006Page 34
SQL AggregationSQL AggregationMIN()MIN() Function Function
The The MIN()MIN() function: function: Requires a scalar type or subtypeRequires a scalar type or subtype Can use an analytical function, like Can use an analytical function, like PARTITION BYPARTITION BY
MIN(column_name)MIN(column_name) This approach finds the lowest value of an This approach finds the lowest value of an
expression, ASCII values are used for strings.expression, ASCII values are used for strings. NULLNULL are sorted last in ascending order and first in are sorted last in ascending order and first in
descending order.descending order.
MIN(column_name)MIN(column_name)OVER (PARTITION BY column_name)OVER (PARTITION BY column_name) This approach finds the lowest value of an expression This approach finds the lowest value of an expression
based on its relationship in the result set to the based on its relationship in the result set to the partitioning column, ASCII values are used for strings.partitioning column, ASCII values are used for strings.
NULLNULL are sorted first in ascending order and last in are sorted first in ascending order and last in descending order.descending order.
Copyright 2006Page 35
SQL AggregationSQL AggregationMIN()MIN() Function: Finds minimum Function: Finds minimum
valuevalue
SELECT MIN(a.column_name)SELECT MIN(a.column_name)
FROM a_table a;FROM a_table a;
Copyright 2006Page 36
SQL AggregationSQL AggregationMIN()MIN() Function: Finds minimum Function: Finds minimum
valuevalue
SELECT MIN(value_list)SELECT MIN(value_list)
FROM counting;FROM counting;
Contains two copies of the Contains two copies of the single digit ordinal numbers, single digit ordinal numbers, and two null values.and two null values.
It returns the lowest number It returns the lowest number without any grouping or without any grouping or partitioning.partitioning.
MIN(VALUE_LIST)MIN(VALUE_LIST)
------------------------------
99
1 row selected.1 row selected.
Copyright 2006Page 37
SQL AggregationSQL AggregationMIN()MIN() Function: Finds minimum Function: Finds minimum
valuevalue
SELECT MAX(a.column_name1)SELECT MAX(a.column_name1)
OVER (PARTITION BY a.column_name2)OVER (PARTITION BY a.column_name2)
FROM a_table a;FROM a_table a;
Copyright 2006Page 38
SQL AggregationSQL AggregationMIN()MIN() Function: Finds minimum Function: Finds minimum
valuevalue
SELECT a.column_name1SELECT a.column_name1
, MIN(a.column_name2), MIN(a.column_name2)
FROM a_table aFROM a_table a
GROUP BY a.column_name1;GROUP BY a.column_name1;
Copyright 2006Page 39
SQL AggregationSQL AggregationMIN()MIN() Function: Finds minimum Function: Finds minimum
valuevalue
SELECT value_listSELECT value_list
, MIN(value_list), MIN(value_list)
FROM countingFROM counting
GROUP BY value_list;GROUP BY value_list;
Contains two copies of the Contains two copies of the single digit ordinal numbers, single digit ordinal numbers, and two null values.and two null values.
Grouping by the Grouping by the VALUE_LISTVALUE_LIST value, the minimum is the value, the minimum is the value in the column.value in the column.
VALUE_LIST MIN(VALUE_LIST)VALUE_LIST MIN(VALUE_LIST)
---------- ------------------------- ---------------
0 00 0
1 11 1
2 22 2
3 33 3
4 44 4
5 55 5
6 66 6
7 77 7
8 88 8
9 99 9
11 rows selected.11 rows selected.
Copyright 2006Page 40
SQL AggregationSQL AggregationMIN()MIN() Function: Finds minimum Function: Finds minimum
valuevalue
SELECT a.column_name1SELECT a.column_name1
, MIN(a.column_name2), MIN(a.column_name2)
OVER (PARTITION BY a.column_name1)OVER (PARTITION BY a.column_name1)
FROM a_table aFROM a_table a
GROUP BY a.column_name1;GROUP BY a.column_name1;
Copyright 2006Page 41
SQL AggregationSQL AggregationMIN()MIN() Function: Finds minimum Function: Finds minimum
valuevalue
SELECT DISTINCTSELECT DISTINCT
value_namevalue_name
, MIN(value_list), MIN(value_list)
OVEROVER
(PARTITION BY value_name)(PARTITION BY value_name)
FROM counting;FROM counting;
Contains two copies of the Contains two copies of the single digit ordinal numbers, single digit ordinal numbers, and two null values.and two null values.
The The OVEROVER clause disallows clause disallows the use of the the use of the GROUP BYGROUP BY clause and a clause and a DISTINCTDISTINCT provides meaningful results.provides meaningful results.
VALUE_NAME MIN(VALUE_LIST)VALUE_NAME MIN(VALUE_LIST)
---------- ------------------------- ---------------
1ST Set 01ST Set 0
2ND Set 02ND Set 0
2 rows selected.2 rows selected.
Copyright 2006Page 42
SQL AggregationSQL AggregationGROUP BYGROUP BY Clause Clause
The The GROUP BYGROUP BY clause lets you group a result clause lets you group a result set by a condition, column value, or set by a condition, column value, or combination of both.combination of both.
The The GROUP BYGROUP BY clause works: clause works: After any After any WHEREWHERE clause clause Once for any query component, and can be different Once for any query component, and can be different
for two queries joined by a set operator into a master for two queries joined by a set operator into a master queryquery
May follow or precede the May follow or precede the HAVINGHAVING clause clause
The The GROUP BYGROUP BY works on data type rules and works on data type rules and standard operator precedence.standard operator precedence.
Copyright 2006Page 43
SQL AggregationSQL AggregationGROUP BYGROUP BY Clause Clause
SELECT a.column_name1SELECT a.column_name1
, SUM(a.column_name2), SUM(a.column_name2)
FROM a_table aFROM a_table a
GROUP BY a.column_name1;GROUP BY a.column_name1;
Copyright 2006Page 44
SQL AggregationSQL AggregationHAVINGHAVING Clause Clause
The The HAVINGHAVING clause lets you group a result set by clause lets you group a result set by evaluating an expression, which can be a evaluating an expression, which can be a aggregation function result compared to a aggregation function result compared to a literal.literal.
The The HAVINGHAVING clause works: clause works: After any After any WHEREWHERE clause clause Once for any query component, and can be different Once for any query component, and can be different
for two queries joined by a set operator into a master for two queries joined by a set operator into a master queryquery
May follow or precede the May follow or precede the GROUP BYGROUP BY clause clause
The The HAVINGHAVING clause works using SQL comparison clause works using SQL comparison operators.operators.
Copyright 2006Page 45
SQL AggregationSQL AggregationHAVING BYHAVING BY Clause Clause
SELECT a.column_name1SELECT a.column_name1
, a.column_name2, a.column_name2
FROM a_table aFROM a_table a
HAVING COUNT(a.column_name3) > 1;HAVING COUNT(a.column_name3) > 1;
Copyright 2006Page 46
SQL AggregationSQL AggregationORDER BYORDER BY Clause Clause
The The ORDER BYORDER BY clause lets you sort a result set. clause lets you sort a result set.
The The ORDER BYORDER BY clause works: clause works: After any After any GROUP BYGROUP BY clause clause Only once for a set of queriers joined by one or more Only once for a set of queriers joined by one or more
set operators into a master queryset operators into a master query By following the By following the GROUP BYGROUP BY clause clause
The The ORDER BYORDER BY works on data type rules: works on data type rules: The The DATEDATE type is sorted by the numeric value of the type is sorted by the numeric value of the
timestamp.timestamp. The The VARCHAR2VARCHAR2 type is sorted by ASCII values, a type is sorted by ASCII values, a ''JANJAN''
and and ''FEBFEB'' from a from a TO_CHAR(date_column,TO_CHAR(date_column,''MONMON'')) will sort will sort ''FEBFEB'' first. first.
Copyright 2006Page 47
SQL AggregationSQL AggregationORDER BYORDER BY Clause Clause
SELECT a.column_name1SELECT a.column_name1
, a.column_name2, a.column_name2
FROM a_table aFROM a_table a
ORDER BY a.column_name1ORDER BY a.column_name1
, a.column_name2;, a.column_name2;
Copyright 2006Page 48
SQL AggregationSQL AggregationORDER BYORDER BY Clause Clause
SELECT a.column_name1SELECT a.column_name1
, a.column_name2, a.column_name2
FROM a_table aFROM a_table a
ORDER BY 1ORDER BY 1
, 2;, 2;
Copyright 2006Page 49
SummarySummary
Copyright 2006Page 50