1. 程式人生 > 實用技巧 >SQL筆記續補

SQL筆記續補

case when then

等價於if xxx return xxx else xxx

就是按條件進行篩選

-- Identify the home team as Bayern Munich, Schalke 04, or neither
SELECT 
    CASE WHEN hometeam_id = 10189 THEN 'FC Schalke 04'  #簡單的來說就是按照條件進行查詢
         WHEN hometeam_id = 9823 THEN 'FC Bayern Munich'
         ELSE 'Other' END AS home_team,
	COUNT(id) AS total_matches
FROM matches_germany
-- Group by the CASE statement alias
GROUP BY home_team;

demo

SELECT 
	c.name AS country,
    -- Count games from the 2012/2013 season
	COUNT(CASE WHEN m.season = '2012/2013' 
          	   THEN m.id ELSE NULL END) AS matches_2012_2013
FROM country AS c
LEFT JOIN match AS m
ON c.id = m.country_id
-- Group by country name alias
GROUP BY country;

country	matches_2012_2013
Portugal	240
France	380
Scotland	228
Netherlands	306
Spain	380
Belgium	240
Italy	380
Germany	306
England	380
Switzerland	180
Poland	240
Showing 11 out of 11 rows


SELECT 
	m.date,
	--Select the team long name column and call it 'opponent'
	t.team_long_name AS opponent, 
	-- Complete the CASE statement with an alias
	CASE WHEN m.home_goal > m.away_goal THEN 'Home win!'
         WHEN m.home_goal < m.away_goal THEN 'Home loss :('
         ELSE 'Tie' END AS outcome
FROM matches_spain AS m
-- Left join teams_spain onto matches_spain
LEFT JOIN teams_spain AS t  #兩個列表根據id進行合併
ON m.awayteam_id = t.team_api_id;


date	          outcome
2012-01-21	Home loss :(
2012-01-22	Home win!
2012-01-22	Home loss :(
2012-01-23	Home win!
2012-01-21	Tie
2012-01-22	Tie
2012-01-21	Home loss :(
2012-01-21	Home win!
2012-01-22	Tie
2012-01-22	Home loss :(
2011-10-26	Tie
2011-10-27	Home win!
2011-10-26	Home loss :(
2011-10-26	Home win!
2011-10-27	Home win!
2011-10-26	Home win!
2011-10-25	Tie
2011-10-26	Home loss :(
2011-10-26	Home win!
2011-10-25	Home loss :(
2011-10-30	Home win!
2011-10-30	Home win!
2011-10-30	Tie
2011-10-29	Home loss :(
2011-10-30	Home win!
2011-10-29	Home win!
2011-10-31	Home loss :(
2011-10-29	Home win!
2011-10-30	Home win!
2011-10-29	Home win!
2011-11-06	Home win!
2011-11-06	Tie
2011-11-06	Home win!
2011-11-06	Tie
2011-11-05	Tie
2011-11-05	Home loss :(
2011-11-05	Tie
2011-11-06	Tie
2011-11-06	Home win!
2011-11-06	Tie
2011-11-20	Tie
2011-12-07	Tie
2011-11-20	Home win!
2011-11-19	Home win!
2011-11-20	Home loss :(
2011-11-19	Home loss :(
2011-11-21	Home loss :(
2011-11-19	Home win!
2011-11-20	Tie
2011-11-20	Home win!
2011-11-27	Home loss :(
2011-11-27	Home win!
2011-11-27	Home win!
2011-11-27	Home loss :(
2011-11-27	Home loss :(
2011-11-26	Home win!
2011-11-28	Home win!
2011-11-27	Home loss :(
2011-11-26	Home loss :(
2011-11-26	Home win!
2011-12-04	Home win!
2011-12-03	Home win!
2011-12-05	Home win!
2011-12-03	Home win!
2011-12-03	Home win!
2011-12-04	Home win!
2011-12-04	Tie
2011-12-03	Home loss :(
2011-12-04	Home win!
2011-12-04	Home win!
2011-12-11	Tie
2011-12-11	Home loss :(
2011-12-11	Home loss :(
2011-12-11	Tie
2011-12-11	Home win!
2011-12-11	Home win!
2011-12-10	Home win!
2011-12-10	Home win!
2011-12-11	Tie
2011-12-10	Home loss :(
2011-12-17	Home loss :(
2011-12-18	Tie
2011-12-18	Home win!
2011-12-18	Home loss :(
2011-12-17	Home loss :(
2011-12-18	Home win!
2011-12-17	Home win!
2011-11-29	Home win!
2011-12-18	Home win!
2011-12-17	Home loss :(
2012-01-08	Tie
2012-01-07	Tie
2012-01-07	Home win!
2012-01-08	Home win!
2012-01-08	Tie
2012-01-08	Home win!
2012-01-07	Tie
2012-01-08	Tie
2012-01-07	Tie
2012-01-07	Home win!
Showing 100 out of 380 rows

demo2

SELECT 
	date,
	-- Identify the home team as Barcelona or Real Madrid
	CASE WHEN hometeam_id = 8634 THEN 'FC Barcelona' 
         ELSE 'Real Madrid CF' END AS home,
    -- Identify the away team as Barcelona or Real Madrid
	CASE WHEN awayteam_id = 8634 THEN 'FC Barcelona' 
         ELSE 'Real Madrid CF' END AS away
FROM matches_spain
WHERE (awayteam_id = 8634 OR hometeam_id = 8634)
      AND (awayteam_id = 8633 OR hometeam_id = 8633); -- where 後面一般填寫各種條件,簡單的條件

date	home	away
2011-12-10	Real Madrid CF	FC Barcelona
2012-04-21	FC Barcelona	Real Madrid CF

demo3

SELECT
	date,
	CASE WHEN hometeam_id = 8634 THEN 'FC Barcelona' 
         ELSE 'Real Madrid CF' END as home,
	CASE WHEN awayteam_id = 8634 THEN 'FC Barcelona' 
         ELSE 'Real Madrid CF' END as away,
	-- Identify all possible match outcomes
	CASE WHEN home_goal > away_goal AND hometeam_id = 8634 THEN 'Barcelona win!'
         WHEN home_goal > away_goal AND hometeam_id = 8633 THEN 'Real Madrid win!' -- 很多的篩選的條件
         WHEN home_goal < away_goal AND awayteam_id = 8634 THEN 'Barcelona win!'
         WHEN home_goal < away_goal AND awayteam_id = 8633 THEN 'Real Madrid win!'
         ELSE 'Tie!' END AS outcome
FROM matches_spain
WHERE (awayteam_id = 8634 OR hometeam_id = 8634)
      AND (awayteam_id = 8633 OR hometeam_id = 8633);

date	home	away	outcome
2011-12-10	Real Madrid CF	FC Barcelona	Barcelona win!
2012-04-21	FC Barcelona	Real Madrid CF	Real Madrid win!

Filtering your CASE statement

過濾資料

-- Select team_long_name and team_api_id from team
SELECT
	team_long_name,
	team_api_id
FROM teams_italy
-- Filter by team long name
WHERE team_long_name = 'Bologna';

team_long_name	team_api_id
Bologna	9857

demo1

-- Select the season and date columns
SELECT 
	season,
	date,
    -- Identify when Bologna won a match
	CASE WHEN hometeam_id = 9857 AND home_goal > away_goal THEN 'Bologna Win'
         WHEN awayteam_id = 9857 AND away_goal > home_goal THEN 'Bologna Win' 
         END AS outcome
FROM matches_italy;


demo2

-- Select the season, date, home_goal, and away_goal columns
SELECT 
	season,
	date,
	home_goal,
	away_goal
FROM matches_italy
WHERE
-- Exclude games not won by Bologna
	CASE WHEN hometeam_id = 9857 AND home_goal > away_goal THEN 'Bologna Win'
         WHEN awayteam_id = 9857 AND away_goal > home_goal THEN 'Bologna Win' 
         END IS NOT NULL;

season	date	home_goal	away_goal
2011/2012	2011-10-30	3	1
2011/2012	2011-12-04	1	0
2011/2012	2012-01-08	2	0
2011/2012	2012-02-21	2	0
2011/2012	2012-02-17	0	3
2011/2012	2012-04-12	1	0
2011/2012	2012-04-29	3	2
2011/2012	2012-05-02	0	1
2011/2012	2012-05-06	2	0
2011/2012	2011-10-16	0	2
2011/2012	2011-10-26	0	1
2012/2013	2012-11-18	3	0
2012/2013	2012-12-02	2	1
2012/2013	2012-12-16	2	3
2012/2013	2013-01-12	4	0
2012/2013	2013-02-03	2	3
2012/2013	2013-02-26	2	1
2012/2013	2013-03-03	3	0
2012/2013	2013-03-10	0	1
2012/2013	2012-09-16	2	3
2012/2013	2013-05-12	0	2
2012/2013	2012-09-30	4	0
2013/2014	2013-10-30	0	3
2013/2014	2013-12-22	1	0
2013/2014	2014-02-09	1	2
2013/2014	2014-03-23	1	0
2013/2014	2013-10-27	1	0

case when + 聚合函式

SELECT 
	c.name AS country,
    -- Count matches in each of the 3 seasons
	COUNT(CASE WHEN m.season = '2012/2013' THEN m.id END) AS matches_2012_2013,
	COUNT(CASE WHEN m.season = '2013/2014' THEN m.id END) AS matches_2013_2014,
	COUNT(CASE WHEN m.season = '2014/2015' THEN m.id END) AS matches_2014_2015
FROM country AS c
LEFT JOIN match AS m
ON c.id = m.country_id
-- Group by country name alias
GROUP BY country;

country	matches_2012_2013
Portugal	240
France	380
Scotland	228
Netherlands	306
Spain	380
Belgium	240
Italy	380
Germany	306
England	380
Switzerland	180
Poland	240
Showing 11 out of 11 rows

AS 後面往往都是新增的列,或者說按照條件篩選出來的列

SELECT 
	c.name AS country,
    -- Count matches in each of the 3 seasons
	COUNT(CASE WHEN m.season = '2012/2013' THEN m.id END) AS matches_2012_2013,
	COUNT(CASE WHEN m.season = '2013/2014' THEN m.id END) AS matches_2013_2014,
	COUNT(CASE WHEN m.season = '2014/2015' THEN m.id END) AS matches_2014_2015
FROM country AS c
LEFT JOIN match AS m
ON c.id = m.country_id
-- Group by country name alias
GROUP BY country;

country	    matches_2012_2013	matches_2013_2014	matches_2014_2015
Portugal	  240	240	306
France	380	380	380
Scotland	228	228	228
Netherlands	306	306	306
Spain	380	380	380
Belgium	240	12	240
Italy	380	380	379
Germany	306	306	306
England	380	380	380
Switzerland	180	180	180
Poland	240	240	240
Showing 11 out of 11 rows

demo2

case when + sum

SELECT 
	c.name AS country,
    -- Sum the total records in each season where the home team won
	SUM(CASE WHEN m.season = '2012/2013' AND m.home_goal > m.away_goal 
        THEN 1 ELSE 0 END) AS matches_2012_2013,
	SUM(CASE WHEN m.season = '2013/2014' AND m.home_goal > m.away_goal 
        THEN 1 ELSE 0 END) AS matches_2013_2014,
	SUM(CASE WHEN m.season = '2014/2015' AND m.home_goal > m.away_goal 
        THEN 1 ELSE 0 END) AS matches_2014_2015
FROM country AS c
LEFT JOIN match AS m
ON c.id = m.country_id
-- Group by country name alias
GROUP BY country;

country	matches_2012_2013	matches_2013_2014	matches_2014_2015
Portugal	103	108	137
France	170	168	181
Scotland	89	102	102
Netherlands	137	144	138
Spain	189	179	171
Belgium	102	6	106
Italy	177	181	152
Germany	130	145	145
England	166	179	172
Switzerland	84	82	76
Poland	97	110	114
Showing 11 out of 11 rows

突然考慮可以做分箱和對映,就是對映和賦值

demo3

SELECT 
	c.name AS country,
    -- Sum the home wins, away wins, and ties in each country
    COUNT(CASE WHEN m.home_goal > m.away_goal THEN m.id 
        END) AS home_wins,
    COUNT(CASE WHEN m.home_goal < m.away_goal THEN m.id 
        END) AS away_wins,
    COUNT(CASE WHEN m.home_goal = m.away_goal THEN m.id 
        END) AS ties
FROM country AS c
LEFT JOIN matches AS m
ON c.id = m.country_id
GROUP BY country;

country	home_wins	away_wins	ties
Portugal	245	156	145
France	349	215	196
Scotland	204	158	94
Netherlands	282	173	157
Spain	350	233	177
Belgium	112	78	62
Italy	333	216	210
Germany	290	176	146
England	351	238	171
Switzerland	158	113	89
Poland	224	117	139
Showing 11 out of 11 rows

demo4

SELECT 
	c.name AS country,
    -- Round the percentage of tied games to 2 decimal points
	ROUND(AVG(CASE WHEN m.season='2013/2014' AND m.home_goal = m.away_goal THEN 1
			 WHEN m.season='2013/2014' AND m.home_goal != m.away_goal THEN 0
			 END),2) AS pct_ties_2013_2014,
	ROUND(AVG(CASE WHEN m.season='2014/2015' AND m.home_goal = m.away_goal THEN 1
			 WHEN m.season='2014/2015' AND m.home_goal != m.away_goal THEN 0
			 END),2) AS pct_ties_2014_2015
FROM country AS c
LEFT JOIN matches AS m
ON c.id = m.country_id
GROUP BY country;

country	pct_ties_2013_2014	pct_ties_2014_2015
Portugal	0.25	0.28
France	0.28	0.23
Scotland	0.22	0.19
Netherlands	0.27	0.24
Spain	0.23	0.24
Belgium	0.17	0.25
Italy	0.24	0.32
Germany	0.21	0.27
England	0.21	0.24
Switzerland	0.23	0.27
Poland	0.30	0.28
Showing 11 out of 11 rows

WHERE are the Subqueries?

子查詢,或者說巢狀查詢