1> /* Advanced SQL Programming Fall 2002*/ 2> /* */ 3> /* Take-home exercises, Nov. 25th */ 4> /* */ 5> use evelyn 1> /* */ 2> /* 1. Average, median, and mode of product prices: */ 3> /* */ 4> /* - Average - */ 5> /* */ 6> select avg(price) AveragePrice from product AveragePrice ------------------------ 60.80 (1 row affected) 1> /* */ 2> /* - Mode - */ 3> /* */ 4> /* a. List prices in order so we can see what we have: */ 5> /* */ 6> select name, price 7> from product 8> where price is not null 9> order by price name price -------------------- ------------------------ cook & book 19.99 paper dolls 19.99 home poll kit 19.99 memory manager 19.99 more paper dolls 19.99 nt guru 20.00 bug stories 20.00 how multi is media? 20.00 money master 29.00 typing test 29.99 blood & guts 29.99 C++ for kids 39.99 star systems 39.99 mortgage minder 39.99 bugbane 49.00 tax time 49.99 teach yourself greek 49.99 landlord logs 89.99 memory tripler 119.99 z_connector 149.00 memory8 400.00 (21 rows affected) 1> /* */ 2> /* b. Find count (= frequency) of each price: */ 3> /* */ 4> select price, count(*) Frequency 5> from product 6> where price is not null 7> group by price 8> order by Frequency price Frequency ------------------------ ----------- 29.00 1 49.00 1 89.99 1 119.99 1 149.00 1 400.00 1 29.99 2 49.99 2 20.00 3 39.99 3 19.99 5 (11 rows affected) 1> /* */ 2> /* c. Find highest frequency, i.e., mode of price: */ 3> /* */ 4> select price, count(*) Mode 5> from product 6> where price is not null 7> group by price 8> having count(*) >= all 9> (select count(*) 10> from product 11> group by price) price Mode ------------------------ ----------- 19.99 5 (1 row affected) 1> /* */ 2> /* - Median price - Celko's first median, separate views. */ 3> /* */ 4> /* Smallest value in upper half: */ 5> /* */ 6> create view small 7> as 8> select min(price) MinTopHalf 9> from product 10> where price is not null 11> and price in 12> (select p1.price 13> from product p1, product p2 14> where p2.price >= p1.price 15> and p1.price is not null 16> group by p1.price 17> having count(p1.price) <= 18> (select ceiling(count(*) / 2.0) 19> from product)) 1> /* */ 2> select * from small MinTopHalf ------------------------ 49.00 (1 row affected) 1> /* */ 2> /* Highest value in lower half: */ 3> /* */ 4> create view big 5> as 6> select max(price) MaxLowHalf 7> from product 8> where price is not null 9> and price in 10> (select p1.price 11> from product p1, product p2 12> where p2.price <= p1.price 13> and p1.price is not null 14> group by p1.price 15> having count(p1.price) <= 16> (select ceiling(count(*) / 2.0) 17> from product)) 1> /* */ 2> select * from big MaxLowHalf ------------------------ 29.00 (1 row affected) 1> /* */ 2> /* Average the two values: */ 3> /* */ 4> select convert(numeric(6,2), ((MinTopHalf + MaxLowHalf) / 2.0)) 5> Median_1 6> from small, big Median_1 --------- 39.00 (1 row affected) 1> /* */ 2> /* - Median price - using Murchison's median, Celko, p.357 */ 3> /* */ 4> select avg(price) Median_2 5> from product p1 6> where exists 7> (select count(*) 8> from product p2 9> where p2.price >= p1.price 10> having count(*) = 11> (select floor(count(*) / 2.0) 12> from product) 13> or count(*) = 14> (select ceiling(count(*) / 2.0) 15> from product)) Median_2 ------------------------ 39.99 (1 row affected) 1> /* Check on how difference arises between expected median and */ 2> /* Murchison's median - probably rounding in ceiling, floor. */ 3> /* */ 4> -- Check values: price, prodnum 5> select price, prodnum 6> from product 7> order by price price prodnum ------------------------ ----------- 19.99 1084 19.99 1105 19.99 2000 19.99 2047 19.99 2049 20.00 1255 20.00 1357 20.00 1457 29.00 1083 29.99 1099 29.99 1108 39.99 1107 39.99 1109 39.99 1110 49.00 2113 49.99 1104 49.99 2050 89.99 2110 119.99 2111 149.00 1106 400.00 1794 (21 rows affected) 1> -- 2> -- Murchison's median, original data, 21 rows -- This time contenating prodnum to make values unique 3> -- 4> select avg(price) 5> from product p1 6> where exists 7> (select count(*) 8> from product p2 9> where convert(char(10), p2.price) + convert(char(4), p2.prodnum) >= 10> convert(char(10), p1.price) + convert(char(4), p1.prodnum) 11> having count(*) = 12> (select floor(count(*) / 2.0) from product) 13> or count(*) = 14> (select ceiling(count(*) / 2.0 ) from product)) ------------------------ 34.99 (1 row affected) 1> -- 2> -- Check floor and ceiling results 3> -- 4> select floor(count(*) / 2.0) LowestTopHalf from product 5> select ceiling(count(*) / 2.0) HighestLowHalf from product LowestTopHalf -------------------- 10 (1 row affected) HighestLowHalf -------------------- 11 (1 row affected) /* */ 1> /* 2. (Mode allowing for 10% difference) */ 2> /* */ 3> /* Original data shows no difference for mode + or - 10%, so*/ 4> /* will use + or - 40% here, to demonstrate the difference. */ 5> /* */ 6> select count (price) Frequency, avg(price) Mode 7> from product 8> group by price 9> having count(*) >= all 10> -- (select count(*) * .9 NOTE: No other values within 10% of mode 11> (select count(*) * .6 -- Max frequency is 5; next closest is 3 12> from product 13> group by price) Frequency Mode ----------- ------------------------ 5 19.99 3 20.00 3 39.99 (3 rows affected) 1> /* */ 2> /* 3. Running total of revenue by order num. and product num. */ 3> /* */ 4> /* - Revenue by order and product, w/o running total, as view -*/ 5> /* */ 6> create view RevByLine 7> as 8> select 9> convert(char(2), d.ordnum) Order#, convert(char(4), d.prodnum) Prod#, 10> unit, convert(numeric(6,2), price) Price, sum(unit*price) LineTotal 11> from orderdetail d, product p 12> where d.prodnum = p.prodnum 13> group by d.ordnum, d.prodnum, unit, price 1> /* */ 2> select * from RevByLine Order# Prod# unit Price LineTotal ------ ----- ------ --------- ------------------------ 81 1106 2 149.00 298.00 81 1357 1 20.00 20.00 81 2050 5 49.99 249.95 84 1099 1 29.99 29.99 84 1255 1 20.00 20.00 84 2050 1 49.99 49.99 85 1794 1 400.00 400.00 85 2050 25 49.99 1,249.75 86 1083 7 29.00 203.00 86 1105 20 19.99 399.80 86 2000 2 19.99 39.98 87 1083 1 29.00 29.00 87 1105 20 19.99 399.80 87 1106 1 149.00 149.00 87 1794 1 400.00 400.00 87 2000 20 19.99 399.80 87 2113 1 49.00 49.00 89 2050 2 49.99 99.98 90 2110 1 89.99 89.99 91 1107 7 39.99 279.93 91 2111 5 119.99 599.95 92 2050 3333 49.99 166,616.67 93 1105 1 19.99 19.99 93 2050 5 49.99 249.95 94 1083 5 29.00 145.00 94 1108 1 29.99 29.99 95 1083 2 29.00 58.00 95 1105 1 19.99 19.99 95 1108 1 29.99 29.99 95 1255 1 20.00 20.00 99 2047 6 19.99 119.94 99 2050 2222 49.99 111,077.78 (32 rows affected) 1> /* */ 2> /* - Running Total on view - */ 3> /* */ 4> select r.Order#, r.Prod#, r.LineTotal, 5> (select sum(r2.LineTotal) 6> from RevByLine r2 7> where r.Order# >= r2.Order#) RunningTotal 8> from RevByLine r 9> order by r.Order# -- already grouped, ordered by Prod# Order# Prod# LineTotal RunningTotal ------ ----- ------------------------ ------------------------ 81 1106 298.00 567.95 81 1357 20.00 567.95 81 2050 249.95 567.95 84 1099 29.99 667.93 84 1255 20.00 667.93 84 2050 49.99 667.93 85 1794 400.00 2,317.68 85 2050 1,249.75 2,317.68 86 1083 203.00 2,960.46 86 1105 399.80 2,960.46 86 2000 39.98 2,960.46 87 1083 29.00 4,387.06 87 1105 399.80 4,387.06 87 1106 149.00 4,387.06 87 1794 400.00 4,387.06 87 2000 399.80 4,387.06 87 2113 49.00 4,387.06 89 2050 99.98 4,487.04 90 2110 89.99 4,577.03 91 1107 279.93 5,456.91 91 2111 599.95 5,456.91 92 2050 166,616.67 172,073.58 93 1105 19.99 172,343.52 93 2050 249.95 172,343.52 94 1083 145.00 172,518.51 94 1108 29.99 172,518.51 95 1083 58.00 172,646.49 95 1105 19.99 172,646.49 95 1108 29.99 172,646.49 95 1255 20.00 172,646.49 99 2047 119.94 283,844.21 99 2050 111,077.78 283,844.21 (32 rows affected) 1> /* */ 2> /* - Create view with numbered rows to use for running sum -*/ 3> /* */ 4> create view RevNumberedLines 5> as 6> select Order#, Prod#, (r1.Order#+"."+r1.Prod#) CalcOrd#, LineTotal, 7> (select count(*) 8> from RevByLine r2 9> where (r2.Order#+"."+r2.Prod#) < (r1.Order#+"."+r1.Prod#)) + 1 10> LineNum 11> from RevByLine r1 1> /* */ 2> select * from RevNumberedLines 3> order by CalcOrd# Order# Prod# CalcOrd# LineTotal LineNum ------ ----- -------- ------------------------ ----------- 81 1106 81.1106 298.00 1 81 1357 81.1357 20.00 2 81 2050 81.2050 249.95 3 84 1099 84.1099 29.99 4 84 1255 84.1255 20.00 5 84 2050 84.2050 49.99 6 85 1794 85.1794 400.00 7 85 2050 85.2050 1,249.75 8 86 1083 86.1083 203.00 9 86 1105 86.1105 399.80 10 86 2000 86.2000 39.98 11 87 1083 87.1083 29.00 12 87 1105 87.1105 399.80 13 87 1106 87.1106 149.00 14 87 1794 87.1794 400.00 15 87 2000 87.2000 399.80 16 87 2113 87.2113 49.00 17 89 2050 89.2050 99.98 18 90 2110 90.2110 89.99 19 91 1107 91.1107 279.93 20 91 2111 91.2111 599.95 21 92 2050 92.2050 166,616.67 22 93 1105 93.1105 19.99 23 93 2050 93.2050 249.95 24 94 1083 94.1083 145.00 25 94 1108 94.1108 29.99 26 95 1083 95.1083 58.00 27 95 1105 95.1105 19.99 28 95 1108 95.1108 29.99 29 95 1255 95.1255 20.00 30 99 2047 99.2047 119.94 31 99 2050 99.2050 111,077.78 32 (32 rows affected) 1> /* */ 2> /* - New running total - */ 3> /* */ 4> select r.CalcOrd#, r.Order#, r.Prod#, r.LineTotal, 5> (select sum(r2.LineTotal) 6> from RevNumberedLines r2 7> where r.LineNum >= r2.LineNum) RunningTotal 8> from RevNumberedLines r 9> order by r.CalcOrd# CalcOrd# Order# Prod# LineTotal RunningTotal -------- ------ ----- ------------------------ ------------------------ 81.1106 81 1106 298.00 298.00 81.1357 81 1357 20.00 318.00 81.2050 81 2050 249.95 567.95 84.1099 84 1099 29.99 597.94 84.1255 84 1255 20.00 617.94 84.2050 84 2050 49.99 667.93 85.1794 85 1794 400.00 1,067.93 85.2050 85 2050 1,249.75 2,317.68 86.1083 86 1083 203.00 2,520.68 86.1105 86 1105 399.80 2,920.48 86.2000 86 2000 39.98 2,960.46 87.1083 87 1083 29.00 2,989.46 87.1105 87 1105 399.80 3,389.26 87.1106 87 1106 149.00 3,538.26 87.1794 87 1794 400.00 3,938.26 87.2000 87 2000 399.80 4,338.06 87.2113 87 2113 49.00 4,387.06 89.2050 89 2050 99.98 4,487.04 90.2110 90 2110 89.99 4,577.03 91.1107 91 1107 279.93 4,856.96 91.2111 91 2111 599.95 5,456.91 92.2050 92 2050 166,616.67 172,073.58 93.1105 93 1105 19.99 172,093.57 93.2050 93 2050 249.95 172,343.52 94.1083 94 1083 145.00 172,488.52 94.1108 94 1108 29.99 172,518.51 95.1083 95 1083 58.00 172,576.51 95.1105 95 1105 19.99 172,596.50 95.1108 95 1108 29.99 172,626.49 95.1255 95 1255 20.00 172,646.49 99.2047 99 2047 119.94 172,766.43 99.2050 99 2050 111,077.78 283,844.21 (32 rows affected) 1> /* */ 2> /* Drop all views */ 3> /* */ 4> drop view small 5> drop view big 6> drop view RevByLine 7> drop view RevNumberedLines 1> /* */ 2> dump tran evelyn with truncate_only