SQL - [SELECT | Group By, Having]

솔비·2024년 1월 25일
0

select 절 작동순서






Group By


그룹화하여 데이터를 조회

🧷 Group By 문법


  • 📌 DISTINCT는 ORDER BY를 사용할 수 없지만 GROUP BY 사용시에는 가능하다.
  • crime_status 에서 경찰서별로 그룹화 하여 경찰서 이름을 조회
mysql> SELECT police_station
    -> FROM crime_status
    -> GROUP BY police_station
    -> ORDER BY police_station
    -> LIMIT 5;
+----------------+
| police_station |
+----------------+
| 강남           |
| 강동           |
| 강북           |
| 강서           |
| 관악           |
+----------------+
5 rows in set (0.15 sec)
  • 경찰서 별로 총 발생 범죄 건수를 검색
ERROR 1054 (42S22): Unknown column 'polce_station' in 'field list'
mysql> SELECT police_station, SUM(case_number) AS '발생 범죄 건수'
    -> FROM crime_status
    -> GROUP BY police_station
    -> ORDER BY '발생 범죄 검수' DESC
    -> LIMIT 5;
+----------------+----------------------+
| police_station | 발생 범죄 건수       |
+----------------+----------------------+
| 중부           |                 3463 |
| 종로           |                 2873 |
| 남대문         |                 2271 |
| 서대문         |                 4239 |
| 혜화           |                 2402 |
+----------------+----------------------+
5 rows in set (0.15 sec)
  • 경찰서 별로 평균 범죄 검거 건수를 검색
mysql> SELECT police_station, AVG(case_number) AS '평균 범죄 발생 건수'
    -> FROM crime_status
    -> GROUP BY police_station
    -> ORDER BY '평균 범죄 발생 건수' DESC
    -> LIMIT 5;
+----------------+-----------------------------+
| police_station | 평균 범죄 발생 건수         |
+----------------+-----------------------------+
| 중부           |                    346.3000 |
| 종로           |                    287.3000 |
| 남대문         |                    227.1000 |
| 서대문         |                    423.9000 |
| 혜화           |                    240.2000 |
+----------------+-----------------------------+
5 rows in set (0.15 sec)
  • 경찰서 별 평균 범죄 발생건수와 평균 범죄 검거 건수를 검색
mysql> SELECT police_station, status_type, AVG(case_number) AS '평균 건수'
    -> FROM crime_status
    -> GROUP BY police_station, status_type
    -> ORDER BY '평균 건수' DESC;
+----------------+-------------+---------------+
| police_station | status_type | 평균 건수     |
+----------------+-------------+---------------+
| 중부           | 발생        |      411.4000 |
| 중부           | 검거        |      281.2000 |
| 종로           | 발생        |      338.8000 |
| 종로           | 검거        |      235.8000 |
| 남대문         | 발생        |      270.8000 |
| 남대문         | 검거        |      183.4000 |
| 서대문         | 발생        |      506.6000 |
| 서대문         | 검거        |      341.2000 |
| 혜화           | 발생        |      281.6000 |
| 혜화           | 검거        |      198.8000 |
| 용산           | 발생        |      593.8000 |
| 용산           | 검거        |      411.2000 |
| 성북           | 발생        |      241.6000 |
| 성북           | 검거        |      184.4000 |
| 동대문         | 발생        |      680.2000 |
| 동대문         | 검거        |      493.0000 |
| 마포           | 발생        |      737.6000 |
| 마포           | 검거        |      506.8000 |
| 영등포         | 발생        |     1043.4000 |
| 영등포         | 검거        |      674.2000 |
| 성동           | 발생        |      472.4000 |
| 성동           | 검거        |      354.8000 |
| 동작           | 발생        |      640.0000 |
| 동작           | 검거        |      417.2000 |
| 광진           | 발생        |      720.2000 |
| 광진           | 검거        |      502.2000 |
| 서부           | 발생        |      272.4000 |
| 서부           | 검거        |      213.0000 |
| 강북           | 발생        |      554.0000 |
| 강북           | 검거        |      451.8000 |
| 금천           | 발생        |      519.6000 |
| 금천           | 검거        |      393.2000 |
| 중랑           | 발생        |      745.2000 |
| 중랑           | 검거        |      556.2000 |
| 강남           | 발생        |      950.8000 |
| 강남           | 검거        |      674.6000 |
| 관악           | 발생        |     1052.2000 |
| 관악           | 검거        |      771.6000 |
| 강서           | 발생        |      883.0000 |
| 강서           | 검거        |      678.6000 |
| 강동           | 발생        |      757.6000 |
| 강동           | 검거        |      532.4000 |
| 종암           | 발생        |      271.8000 |
| 종암           | 검거        |      205.0000 |
| 구로           | 발생        |      835.0000 |
| 구로           | 검거        |      596.8000 |
| 서초           | 발생        |      753.0000 |
| 서초           | 검거        |      495.2000 |
| 양천           | 발생        |      643.2000 |
| 양천           | 검거        |      417.2000 |
| 송파           | 발생        |     1082.0000 |
| 송파           | 검거        |      708.8000 |
| 노원           | 발생        |      748.6000 |
| 노원           | 검거        |      516.2000 |
| 방배           | 발생        |      167.2000 |
| 방배           | 검거        |      115.2000 |
| 은평           | 발생        |      405.6000 |
| 은평           | 검거        |      293.2000 |
| 도봉           | 발생        |      435.8000 |
| 도봉           | 검거        |      298.0000 |
| 수서           | 발생        |      520.4000 |
| 수서           | 검거        |      374.4000 |
+----------------+-------------+---------------+
62 rows in set (0.15 sec)







Having


조건에 집계함수가 포함되는 경우 WHERE 대신 HAVING 사용
(sum, avg, .. 등에 조건을 붙히고 싶을 때)

🧷 Having 문법

  • 경찰서 별로 발생한 범죄 건수의 합이 4000 건보다 보다 큰 경우를 검색
mysql> SELECT police_station, SUM(case_number) AS count
    -> FROM crime_status
    -> WHERE status_type LIKE '발생'
    -> GROUP BY police_station
    -> HAVING count > 4000;
+----------------+-------+
| police_station | count |
+----------------+-------+
| 영등포         |  5217 |
| 강남           |  4754 |
| 관악           |  5261 |
| 강서           |  4415 |
| 구로           |  4175 |
| 송파           |  5410 |
+----------------+-------+
6 rows in set (0.15 sec)
  • 경찰서 별로 발생한 폭력과 절도의 범죄 건수 평균이 2000 이상인 경우를 검색
mysql> SELECT police_station, AVG(case_number)
    -> FROM crime_status
    -> WHERE (crime_type LIKE '폭력' or crime_type LIKE '절도') AND status_type LIKE '발생'
    -> GROUP BY police_station
    -> HAVING AVG(case_number) >= 2000;
+----------------+------------------+
| police_station | AVG(case_number) |
+----------------+------------------+
| 영등포         |        2444.5000 |
| 강남           |        2112.0000 |
| 관악           |        2421.5000 |
| 강서           |        2067.0000 |
| 송파           |        2552.0000 |
+----------------+------------------+
5 rows in set (0.15 sec)





연습문제


  1. 경찰서 별로 절도 범죄 평균 발생 건수를 가장 많은 건수 순으로 10개 검색하고 확인하세요.
mysql> SELECT police_station, AVG(case_number)
    -> FROM crime_status
    -> WHERE crime_type LIKE '절도' AND status_type LIKE '발생'
    -> GROUP BY police_station
    -> ORDER BY AVG(case_number) DESC
    -> LIMIT 10;
+----------------+------------------+
| police_station | AVG(case_number) |
+----------------+------------------+
| 송파           |        2429.0000 |
| 관악           |        2229.0000 |
| 영등포         |        2188.0000 |
| 강남           |        1941.0000 |
| 구로           |        1763.0000 |
| 강서           |        1689.0000 |
| 서초           |        1673.0000 |
| 광진           |        1664.0000 |
| 강동           |        1640.0000 |
| 양천           |        1517.0000 |
+----------------+------------------+
10 rows in set (0.15 sec)
  1. 경찰서 별로 가장 많이 검거한 범죄 건수를 가장 적은 건수 순으로 5개 검색하세요.
mysql> SELECT police_station, MAX(case_number)
    -> FROM crime_status
    -> WHERE status_type LIKE '검거'
    -> GROUP BY police_station
    -> ORDER BY MAX(case_number)
    -> LIMIT 5;
+----------------+------------------+
| police_station | MAX(case_number) |
+----------------+------------------+
| 방배           |              365 |
| 남대문         |              494 |
| 성북           |              610 |
| 혜화           |              628 |
| 종암           |              630 |
+----------------+------------------+
5 rows in set (0.15 sec)
  1. 경찰서 별로 가장 적게 검거한 건수 중 4건보다 큰 경우를 건수가 큰 순으로 정렬하여 검색하세요
mysql> SELECT police_station, MIN(case_number)
    -> FROM crime_status
    ->
    -> WHERE status_type LIKE '검거'
    -> GROUP BY police_station
    -> HAVING MIN(case_number) > 4
    -> ORDER BY MIN(case_number) DESC;
+----------------+------------------+
| police_station | MIN(case_number) |
+----------------+------------------+
| 중랑           |                6 |
| 송파           |                6 |
| 동대문         |                5 |
| 강서           |                5 |
| 구로           |                5 |
+----------------+------------------+
5 rows in set (0.15 sec)
  1. '대문' 으로 끝나는 이름의 경찰서 별 범죄발생 건수의 평균이 500건 이상인 경우를 검색하세요
mysql> SELECT police_station, AVG(case_number)
    -> FROM crime_status
    -> WHERE police_station LIKE '%대문' AND  status_type LIKE '발생'
    -> GROUP BY police_station
    -> HAVING AVG(case_number) >= 500;
+----------------+------------------+
| police_station | AVG(case_number) |
+----------------+------------------+
| 서대문         |         506.6000 |
| 동대문         |         680.2000 |
+----------------+------------------+
2 rows in set (0.15 sec)

Daily Study Note
profile
Study Log

0개의 댓글