某圖書館收藏有書籍具有不同的出版年份,管理員需要做一下統計工作:
(1)每一年書籍的數目,如: 2000年有10本書, 2001年有5本書...
(2)每一種書籍的數目,如: 西游記有10本, 三國演義有5本...
(3)每一種書不同年份對應的數目, 如2本西游記在2000出版的,8本在2008年出版...
(4)每一年不同種類書籍的數目,如2000年出版的西游記有2本,三國演義有5本...
(5)某一種書不同年份對應的數目(與(3)的區別在於,(3)需要統計所有的書籍,(5)是統計指定的某一種書籍)
新建表與准備數據(books.sql)
create table `books`( id int not null auto_increment, title varchar(50) not null, year int not null, primary key(id) )Engine=InnoDB default charset=utf8;
建表:
>>> (echo 'use test'; cat books.sql) | mysql - u root --password 密碼;
數據如下:

+----+--------------+------+ | id | title | year | +----+--------------+------+ | 1 | 三國演義 | 2000 | | 2 | 三國演義 | 2000 | | 3 | 三國演義 | 2000 | | 4 | 三國演義 | 2010 | | 5 | 三國演義 | 2010 | | 6 | 紅樓夢 | 2003 | | 7 | 紅樓夢 | 2003 | | 8 | 紅樓夢 | 2003 | | 9 | 紅樓夢 | 2003 | | 10 | 紅樓夢 | 2003 | | 11 | 紅樓夢 | 2016 | | 12 | 紅樓夢 | 2016 | | 13 | 紅樓夢 | 2016 | | 14 | 紅樓夢 | 2012 | | 15 | 紅樓夢 | 2015 | | 16 | 紅樓夢 | 2015 | | 17 | 水滸傳 | 2001 | | 18 | 水滸傳 | 2001 | | 19 | 水滸傳 | 2001 | | 20 | 水滸傳 | 2003 | | 21 | 水滸傳 | 2004 | | 22 | 水滸傳 | 2005 | | 23 | 水滸傳 | 2015 | | 24 | 水滸傳 | 2015 | | 25 | 西游記 | 2015 | | 26 | 西游記 | 2015 | | 27 | 西游記 | 2015 | | 28 | 西游記 | 2015 | | 29 | 西游記 | 2012 | | 30 | 西游記 | 2012 | | 31 | 西游記 | 2014 | | 32 | 西游記 | 2014 | | 33 | 西游記 | 2011 | | 34 | 西游記 | 2011 | +----+--------------+------+ 34 rows in set (0.00 sec)
1.統計每一年書籍的數目
select year, count(1) as book_nums from books group by year;
結果:

+------+-----------+ | year | book_nums | +------+-----------+ | 2000 | 3 | | 2001 | 3 | | 2003 | 6 | | 2004 | 1 | | 2005 | 1 | | 2010 | 2 | | 2011 | 2 | | 2012 | 3 | | 2014 | 2 | | 2015 | 8 | | 2016 | 3 | +------+-----------+ 11 rows in set (0.00 sec)
2.統計每一種書籍的數目
select title, count(1) as book_nums from books group by title;
結果:

+--------------+-----------+ | title | book_nums | +--------------+-----------+ | 三國演義 | 5 | | 水滸傳 | 8 | | 紅樓夢 | 11 | | 西游記 | 10 | +--------------+-----------+ 4 rows in set (0.00 sec)
3.統計每一種書不同年份對應的數目
select title, year, count(1) as book_nums from books group by title, year;
結果:

+--------------+------+-----------+ | title | year | book_nums | +--------------+------+-----------+ | 三國演義 | 2000 | 3 | | 三國演義 | 2010 | 2 | | 水滸傳 | 2001 | 3 | | 水滸傳 | 2003 | 1 | | 水滸傳 | 2004 | 1 | | 水滸傳 | 2005 | 1 | | 水滸傳 | 2015 | 2 | | 紅樓夢 | 2003 | 5 | | 紅樓夢 | 2012 | 1 | | 紅樓夢 | 2015 | 2 | | 紅樓夢 | 2016 | 3 | | 西游記 | 2011 | 2 | | 西游記 | 2012 | 2 | | 西游記 | 2014 | 2 | | 西游記 | 2015 | 4 | +--------------+------+-----------+ 15 rows in set (0.00 sec)
4.統計每一年不同種類書籍的數目
select year, title, count(1) as book_nums from books group by year, title;
結果:

+------+--------------+-----------+ | year | title | book_nums | +------+--------------+-----------+ | 2000 | 三國演義 | 3 | | 2001 | 水滸傳 | 3 | | 2003 | 水滸傳 | 1 | | 2003 | 紅樓夢 | 5 | | 2004 | 水滸傳 | 1 | | 2005 | 水滸傳 | 1 | | 2010 | 三國演義 | 2 | | 2011 | 西游記 | 2 | | 2012 | 紅樓夢 | 1 | | 2012 | 西游記 | 2 | | 2014 | 西游記 | 2 | | 2015 | 水滸傳 | 2 | | 2015 | 紅樓夢 | 2 | | 2015 | 西游記 | 4 | | 2016 | 紅樓夢 | 3 | +------+--------------+-----------+
5.統計某一種書不同年份對應的數目
select title, year, count(1) as book_nums from books where title = "西游記" group by year;
結果:

+-----------+------+-----------+ | title | year | book_nums | +-----------+------+-----------+ | 西游記 | 2011 | 2 | | 西游記 | 2012 | 2 | | 西游記 | 2014 | 2 | | 西游記 | 2015 | 4 | +-----------+------+-----------+
討論:
(1)與(2)結果不同是因為它們分別從年份和書名對書籍進行分類
(3)與(4)結果其實是一樣的,只不過顯示的格式不同,看起來不一樣,兩種方式都是對書籍進行了年份和書名的分類,只是先后順序不同而已
(5) 指定某一種書的進行年份分類,此時有兩種選擇.第一種,先找出所有指定的書籍,再按年份進行分類;第二種,先按年份進行分類,再從不同年份中選出指定的書籍,也可以得到結果.
你會選第一種還是第二種?
先看第一種方式:
第一步找出所有的指定書籍,需要把全部書籍查找一遍;第二步,按年份分類,需要將所有指定的書籍查找一遍
第二種方式:
第一步按年份分類,需要把全部數據查找一遍;第二步,在不同年份書籍中找出指定的數據,相當於再次查找一次全部數據
因此,選擇第一種方式比較合適,先找到指定的書籍,再按照時間分類.
在sql中, where title = '西游記' 代表找到指定的書籍; group by year 表示按時間分類.那么問題來了,sql執行 where 和 group by 時,哪個先執行?
(畢)