Solution Discussion Working with Per-Group and Overall Summary Values Simultaneously

You want t o writ e a query t hat displays a sum m ary, t oget her wit h t he list of records associat ed wit h each sum m ary value.

7.18.2 Solution

Recognize t hat t his is a variant on working wit h different levels of sum m ary inform at ion, and solve t he problem using t he sam e t echniques.

7.18.3 Discussion

Suppose you want t o produce a report t hat looks like t his: Name: Ben; days on road: 3; miles driven: 362 date: 2001-11-29, trip length: 131 date: 2001-11-30, trip length: 152 date: 2001-12-02, trip length: 79 Name: Henry; days on road: 5; miles driven: 911 date: 2001-11-26, trip length: 115 date: 2001-11-27, trip length: 96 date: 2001-11-29, trip length: 300 date: 2001-11-30, trip length: 203 date: 2001-12-01, trip length: 197 Name: Suzi; days on road: 2; miles driven: 893 date: 2001-11-29, trip length: 391 date: 2001-12-02, trip length: 502 The report show s, for each driver in t he driver_log t able, t he following inform at ion: • A sum m ary line showing t he driver nam e, t he num ber of days on t he road, and t he num ber of m iles driven. • A list of t he dat es and m ileages for t he individual t rips from which t he sum m ary values are calculat ed. This scenario is a variat ion on t he different levels of sum m ary inform at ion problem discussed in t he previous recipe. I t m ay not seem like it at first , because one of t he t ypes of inform at ion is a list rat her t han a sum m ary. But t hat s really j ust a level zero sum m ary. This kind of problem appears in m any ot her form s: • You have a dat abase t hat list s cont ribut ions t o candidat es in your polit ical part y. The part y chair request s a print out t hat shows, for each candidat e, t he num ber of cont ribut ions and t ot al am ount cont ribut ed, as well as a list of cont ribut or nam es and addresses. • You want t o m ake a handout for a com pany present at ion t hat sum m arizes t ot al sales per sales region, wit h a list under each region showing t he sales for each st at e in t he region. I n each case, t he solut ions are like t hose discussed in t he previous recipe: • Run separat e queries t o get t he inform at ion for each level of det ail t hat you require. Just as a single query wont produce per-group sum m ary values and an overall sum m ary value at t he sam e t im e, neit her will one query produce per-group sum m ary values and a list of each groups individual records. • Fet ch t he rows t hat m ake up t he list s and perform t he sum m ary calculat ions yourself t o elim inat e t he sum m ary query. Let s use each approach t o produce t he driver report shown at t he beginning of t his sect ion. The following im plem ent at ion in Pyt hon generat es t he report using one query t o sum m arize t he days and m iles per driver, and anot her t o fet ch t he individual t rip records for each driver: select total miles per driver and construct a dictionary that maps each driver name to days on the road and miles driven name_map = { } cursor = conn.cursor cursor.execute SELECT name, COUNTname, SUMmiles FROM driver_log GROUP BY name for name, days, miles in cursor.fetchall : name_map[name] = days, miles select trips for each driver and print the report, displaying the summary entry for each driver prior to the list of trips cursor.execute SELECT name, trav_date, miles FROM driver_log ORDER BY name, trav_date cur_name = for name, trav_date, miles in cursor.fetchall : if cur_name = name: new driver; print drivers summary info print Name: s; days on road: d; miles driven: d \ name, name_map[name][0], name_map[name][1] cur_name = name print date: s, trip length: d trav_date, miles cursor.close By perform ing sum m ary calculat ions in t he program , you can reduce t he num ber of queries required. I f you it erat e t hrough t he t rip list and calculat e t he per-driver day count s and m ileage t ot als yourself, a single query suffices: get list of trips for the drivers cursor = conn.cursor cursor.execute SELECT name, trav_date, miles FROM driver_log ORDER BY name, trav_date rows = cursor.fetchall cursor.close iterate through rows once to construct a dictionary that maps each driver name to days on the road and miles driven the dictionary entries are lists rather than tuples because we need mutable values that can be modified in the loop name_map = { } for name, trav_date, miles in rows: if not name_map.has_key name: initialize entry if nonexistent name_map[name] = [0, 0] name_map[name][0] = name_map[name][0] + 1 count days name_map[name][1] = name_map[name][1] + miles sum miles iterate through rows again to print the report, displaying the summary entry for each driver prior to the list of trips cur_name = for name, trav_date, miles in rows: if cur_name = name: new driver; print drivers summary info print Name: s; days on road: d; miles driven: d \ name, name_map[name][0], name_map[name][1] cur_name = name print date: s, trip length: d trav_date, miles Should you require m ore levels of sum m ary inform at ion, t his t ype of problem get s m ore difficult . For exam ple, you m ight want t he report showing driver sum m aries and t rip logs t o be preceded by a line t hat shows t he t ot al m iles for all drivers: Total miles driven by all drivers combined: 2166 Name: Ben; days on road: 3; miles driven: 362 date: 2001-11-29, trip length: 131 date: 2001-11-30, trip length: 152 date: 2001-12-02, trip length: 79 Name: Henry; days on road: 5; miles driven: 911 date: 2001-11-26, trip length: 115 date: 2001-11-27, trip length: 96 date: 2001-11-29, trip length: 300 date: 2001-11-30, trip length: 203 date: 2001-12-01, trip length: 197 Name: Suzi; days on road: 2; miles driven: 893 date: 2001-11-29, trip length: 391 date: 2001-12-02, trip length: 502 I n t his case, you need eit her anot her query t o produce t he t ot al m ileage, or anot her calculat ion in your program t hat com put es t he overall t ot al.

Chapter 8. Modifying Tables with ALTER TABLE

I nt roduct ion Dropping, Adding, or Reposit ioning a Colum n Changing a Colum n Definit ion or Nam e The Effect of ALTER TABLE on Null and Default Value At t ribut es Changing a Colum ns Default Value Changing a Table Type Renam ing a Table Adding or Dropping I ndexes Elim inat ing Duplicat es by Adding an I ndex Using ALTER TABLE t o Norm alize a Table