오늘은 MySQL 그룹화와 SELECT문을 중복으로 사용하는 것에 대하여 알아보았습니다.
이제 슬슬 데이터를 조회하는데에 조건이 추가되고 여러 문법들이 나오면서 복잡해지는 것 같습니다. 하지만, 그냥 단순하게 조회하는 방식을 활용하는 것 보다는 재미있는 것 같습니다.
MySQL을 통하여 데이터를 조회하다보면, 중복되는 데이터들을 마주하게 될 것입니다.
예를 들어서 다음과 같이 Customers 테이블에서 Country 컬럼을 조회하여 고객들의 나라를 파악한다고 할 때, 우리는 다음과 같은 명령어를 통하여 고객들의 나라를 파악할 것입니다.
SELECT Country FROM Customers;
하지만, 이런 경우에는 다음과 같이 Country에 해당되는 데이터가 모두 출력되므로, 중복되는 데이터들 또한 조회되기 마련입니다.

다음과 같이 멕시코와 독일이 중복되는 것을 확인할 수 있습니다.
이와 같은 데이터의 조회 방식은 나라의 종류만을 파악하고자 하는 경우에 사용자에게 불편함을 줄 수 있습니다.
이와 같은 불편함을 해소하기 위하여, MySQL에서는 데이터를 그룹화하는 방식을 통하여 중복되는 데이터를 제거하여 한 눈에 어떠한 종류의 데이터가 존재하는지 파악할 수 있습니다.
SELECT (데이터) FROM (테이블) GROUP BY (그룹화시킬 데이터)
다음과 같이 GROUP BY 명령어를 통하여 데이터를 그룹화시킬 수 있는데,
위에서 보았던 예시에서처럼 고객들의 나라만을 파악하고자한다면,
SELECT Country FROM Customers GROUP BY Country;
다음의 명령어를 통하여 데이터를 중복되는 대상들은 제외하여 조회할 수 있습니다.

그룹화는 하나의 데이터만이 아니라 여러 개의 데이터를 동시에 그룹화할 수 있는데, 이러한 경우에는 그룹화 할때 사용된 데이터들이 모두 같아야 중복으로 판단되어 그룹화가 진행됩니다.
예를 들어서, 다음과 같이 2개의 데이터를 대상으로 그룹화를 진행한다고 가정해봅시다.
SELECT Country, City FROM Customers GROUP BY Country, City;
Country와 City라는 데이터를 조회하는데, Country와 City를 대상으로 그룹화를 진행하여 조회한다면, 다음과 같이 Country는 같아도 City가 다른 경우도 조회되는 것을 확인할 수 있습니다.

배우면서도 좀 많이 헷갈렸던 SELECT 중복 사용입니다.
SELECT 중복 사용은 말 그대로 SELECT문을 중복으로 활용하여 데이터를 조회하는 방식입니다.
그런데 사실 말이 쉽지, 활용되는 문장들을 보면 쉽지않습니다.
SELECT문을 중복으로 활용하는 방식에는 상관 서브 쿼리 방식과 비상관 서브 쿼리 방식으로 나눌 수 있습니다.
비상관 서브 쿼리 방식은 중복 사용되는 SELECT문이 서로 영향을 주지 않는 상태, 즉 다른 쿼리의 어느 것도 참조하지 않은 상태에서 데이터를 조회나느 방식이며
상관 서브 쿼리 방식은 반대로 중복 사용되는 SELECT문이 서로에게 영향을 주는 상태, 즉 다른 쿼리의 값을 참조하는 방식으로 데이터를 조회하게됩니다.
일단 먼저 비교적 간단한 비상관 서브 쿼리부터 알아보겠습니다.

먼저, 이 테이블의 경우에는 상품의 주문ID, 상품ID, 그리고 수량이 저장되어 있는 OrderDetails 테이블입니다.

다음 테이블의 경우에는 상품의ID, 상품의 이름, 공급자ID, 카테고리ID, 품목, 가격이 저장된 Products 테이블입니다.
우리는 주문된 상품 중에서 특정 가격 이상인 상품들을 조회하고자합니다.
해당 조건을 통하여 데이터를 조회하고자 한다면, 우선 우리는 Products 테이블에서 가격이 특정 가격 이상인 대상들을 구한다음, 그 대상들을 OrderDetails 테이블에서 찾아야합니다.
즉, SELECT문 2개를 활용하여 문제를 해결할 수 있습니다.
SELECT * FROM OrderDetails
WHERE ProductID IN (SELECT ProductID FROM Products WHERE Price >= 20);
그럴 경우 다음의 명령어를 통하여 데이터를 조회할 수 있는데,

SELECT ProductID FROM Products WHERE Price >= 20
해당 명령어를 통하여 가격이 20달러 이상인 제품의 ID를 구한 뒤에,
그것을 OrderDetails 테이블에서 조회하는 방식입니다.
SELECT문을 각각 하나의 쿼리라고 본다면, SELECT * FROM OrderDetails WHERE ProductID IN()은 외부 쿼리가 되고, SELECT ProductID FROM Products WHERE Price >= 20는 내부 쿼리, 즉 서브 쿼리가 됩니다.
외부 쿼리와 서브 쿼리가 서로 쿼리 연산을 하는데에 있어서 영향을 주지 않기 때문에 이러한 방식을 비상관 서브 쿼리 방식이라고합니다.
서브 쿼리에서 연산을 값을 토대로 외부 쿼리에서 연산을 진행하기 때문에 이게 왜 비상관인지 혼란하실수도 있는데 저도 처음엔 그렇게 생각했습니다...
그런데 상관 서브 쿼리 방식을 보고 나시면 좀 감이 잡히실 것 같습니다.
상관 쿼리 방식은 비상관 서브 쿼리 방식과는 다르게 서브 쿼리에서 외부 쿼리를 참조하여 연산을 진행하는 방식입니다.
SELECT * FROM OrderDetails O WHERE
(SELECT P.ProductID FROM Products P
WHERE O.ProductID = P.ProductID AND P.Price>=20);
약간 이러한 방식으로 데이터 조회를 진행하는데,
비상관 서브 쿼리 방식과의 차이점을 알아보자면, 상관 서브 쿼리 방식은 테이블을 참조할 때 활용하는 참조자가 존재한다는 점입니다.
Product 옆에 존재하는 P와 OrderDetails 옆에 존재하는 O의 경우가 그러한 참조자입니다.
해당 참조자를 통하여 서브 쿼리에서도 외부 쿼리의 데이터를 참조하여 쿼리 연산에 활용할 수 있습니다.
이처럼 오늘은 그룹화와 SELECT문 중복 사용에 대하여 알아보았는데, 생각보다 많이 복잡하여 연습이 많이 필요한 것 같습니다ㅜ
내일은 아마 데이터 엮는 JOIN에 대해서 배울 것 같습니다.