Lab 5 – aggregation, functions dates, strings. Sysdate – current date/time 2 Sysdate –...

35
Lab 5 – aggregation, functions dates, strings

Transcript of Lab 5 – aggregation, functions dates, strings. Sysdate – current date/time 2 Sysdate –...

Lab 5 – aggregation, functions dates, strings

Sysdate – current date/time

2

• Sysdate – variable -> returns days!

• If have variable which is date of birth, can calculate age:• Sysdate – dob = age in days

How would you figure out years?

3

How would you figure out years?

4

(Sysdate – dob)/ 365.25

What about age in months?

Functions – loads of them! http://download.oracle.com/docs/cd/

B19306_01/server.102/b14200/functions001.htm#i88893

Functions have at least two pieces function name Open parenthenses The argument(s) passed, normally

separated by commas Sometimes there may be no argument so

this is empty Closing parentheses

5

String function

Upper -> returns the upper case of the argument (string) passed Upper(name)

Lower -> returns the lowercase of the argument (string) passed Lower(name)

Length -> returns the length of a string Length(name)

6

Concatenation

7

+

variable||variable

To make proper name

Fname || ‘ ‘ ||Lname

You can add any constants in between the pipe operators.

i.e. bride_fname || ‘ and her lovely groom’ ||groom_fname

8

Math functions

Round– rounds up or down at the specified number of decimal points Round(n, precision) Try this:

Select (sysdate - appt_date) from vet_appt;

Now round to two decimal places: Select round((sysdate - appt_date), 2) from

vet_appt;

9

Math functions - Trunc

Trunc – truncates at the specified number of decimal points Trunc(n, precision) Select trunc((sysdate - appt_date), 2) from

vet_appt;

Write one query with both – any differences? Select trunc((sysdate - appt_date), 2),

round((sysdate - appt_date), 2) from vet_appt;

10

Aggregation functions

Return only 1 row as an output. The output displays the

mathematical result of one of the following 5 functions: Min Max Avg Sum count

11

12

Aggregate Function OperationsMin, Max, Avg

Function

? Example

Min What’s the least, lowest

Select min(temperature) from vet_apptWhere animal_id =1

Max What’s the highest, most

Select min(temperature) from vet_apptWhere animal_id =1

Avg What’s the average

Select avg(temperature)from vet_apptWhere animal_id =1

13

Aggregate Function OperationsSum, Count

Function

? Example

Sum What’s the total

Select sum(weight) from vet_appt

Count How many Select count(vet_client_id)From vet_client

Distinct Count

Shows the unique number

Select count(distinct(breed)) From animal;

Compare this to:count(breed)From animal;

Rules on Aggregation Can have multiple aggregated

functions (avg(weight), min(weight), max(weight) ) in one query

SQL> Select avg(weight), min(weight), max(weight)

2 From vet_appt, animal, 3 Where animal.breed = 1 and 4 Vet_Appt.animal_id = animal.animal_id;AVG(WEIGHT) MIN(WEIGHT) MAX(WEIGHT)----------- ----------- ----------- 79.0625 79 79.25

14

Aggregation rules, contd.CANNOT have aggregated function (avg, min, max, sum, count) in same select query as non-aggregated data (breed)

SQL> Select breed, avg(weight), min(weight), max(weight)

2 From vet_appt, animal 3 Where animal.breed = 1 and 4 Vet_Appt.animal_id = animal.animal_id;Select breed, avg(weight), min(weight), max(weight) *ERROR at line 1:ORA-00937: not a single-group group function

15

Group by

What if you want to have your output subsorted ?

What is the average weight by breed?

You need a group by!!!

16

Group by

Select avg(weight)From vet_appt, animalWhere vet_appt.animal_id =

animal.animal_id; AVG(WEIGHT)----------- 25.3938596

17

Wait – this is just one row – I want to see it by breed!Select avg(weight)From vet_appt,

animalWhere

vet_appt.animal_id = animal.animal_id

Group by breed;

18

AVG(WEIGHT)----------- 79.0625 15.8596154 13.925 50.225 9.05 34.6666667

6 rows selected.

Can I add breed to my output? – YES since you GROUPED it!!!

Select breed, avg(weight)

From vet_appt, animal

Where vet_appt.animal_id = animal.animal_id

Group by breed; 19

BREED AVG(WEIGHT)---------- ----------- 1 79.0625 8 15.8596154 9 13.925 13 50.225 14 9.05 15 34.6666667

6 rows selected.

Can I add the breed description instead?Select breed_description, avg(weight)From vet_appt, animal, breedWhere vet_appt.animal_id =

animal.animal_id and breed = breed_id

Group by breed_description;

20

The group by indicates on which variable you are creating the distribution. This needs to be the SAME

attribute as in the select statement

Output with breed_descriptionBREED_DESCRIPTION AVG(WEIGHT)

-------------------------------------------------- -----------

Domestic Long Hair 13.925

Domestic Short Hair 15.8596154

Hemingway Polydactyl 9.05

Mixed 50.225

Siberian Husky 79.0625

Southdown Babydoll 34.6666667

6 rows selected.

21

How about an alias and round?Select breed_description as

“Breed”, round(avg(weight),2) as “Average Weight”

From vet_appt, animal, breedWhere vet_appt.animal_id =

animal.animal_id and breed = breed_id

Group by breed_description;

22

Output with rounding and aliasBreed Average Weight

-------------------------------------------------- --------------

Domestic Long Hair 13.93

Domestic Short Hair 15.86

Hemingway Polydactyl 9.05

Mixed 50.23

Siberian Husky 79.06

Southdown Babydoll 34.67

6 rows selected.

23

Can I add a filter?

Select breed_description as “Breed”, round(avg(weight),2) as “Average Weight”

From vet_appt, animal, breedWhere vet_appt.animal_id =

animal.animal_id and breed = breed_id and

Breed = 15Group by breed_description;

24

Sure… here’s with a filterBreed

Average Weight--------------------------------------------------

--------------Southdown Babydoll

34.67

25

Can I filter on my aggregation?Select breed_description as “Breed”,

round(avg(weight),2) as “Average Weight”

From vet_appt, animal, breedWhere vet_appt.animal_id =

animal.animal_id and breed = breed_id andavg(weight) > 30

Group by breed_description; 26

Ooops….

ERROR at line 5:ORA-00934: group function is not allowed here

27

To filter on aggregated data (such as using the function

average, min, max, min, sum in your filter) MUST have a

HAVING clause

HAVING

Need a having clause whenever you are filtering on aggregation.

28

Consider this query:

Select breed_description as “Breed”, round(avg(weight),2) as “Average Weight”

From vet_appt, animal, breedWhere vet_appt.animal_id =

animal.animal_id and breed = breed_id

Group by breed_description;;

29

Here’s the output

Breed Average Weight

-------------------------------------------------- --------------

Domestic Long Hair 13.93

Domestic Short Hair 15.86

Hemingway Polydactyl 9.05

Mixed 50.23

Siberian Husky 79.06

Southdown Babydoll 34.67

6 rows selected.

30

But what if I only want those with the average weight > 30 - Adding HavingSelect breed_description as “Breed”,

round(avg(weight),2) as “Average Weight”

From vet_appt, animal, breedWhere vet_appt.animal_id =

animal.animal_id and breed = breed_id

Group by breed_description

Having avg(weight) > 30 ; 31

Here’s the new output – 3 less recordsBreed

Average Weight--------------------------------------------------

--------------Mixed

50.23Siberian Husky

79.06Southdown Babydoll

34.6732

Can you have aggregated and unaggregated filters in the same query?

Select breed_description as “Breed”, round(avg(weight),2) as “Average Weight”

From vet_appt, animal, breed

Where vet_appt.animal_id = animal.animal_id and

breed = breed_id and

primary_color >3

Group by breed_description

Having avg(weight) >30;

33

The whole shebang

Select client_lname, name, count(vet_appt.appt_id) as “Appt count”

From animal, vet_client, vet_apptWhere vet_client.client_id = animal.client_id

andVet_appt.animal_id = animal.animal_id and

Dob >to_date( ‘01/01/1986’, ‘MM/DD/YYYY’)

Group by client_lname, nameHaving count(animal.animal_id) >=1Order by client_lname asc, name asc;

34

We’ve got a winner!

35