Data Retrieval in SQL: Ambiguous Attribute
Ambiguous Attributes (애매한 속성) 부분에서는 SQL 쿼리에서 동일한 속성 이름이 여러 테이블에 존재할 때 발생하는 혼란과 이를 해결하는 방법에 대해 설명합니다.
1. 문제 상황: 속성 이름의 중복
SQL에서는 두 개 이상의 테이블에 동일한 이름의 속성이 있을 수 있습니다. 예를 들어, DEPARTMENT 테이블과 EMPLOYEE 테이블에 모두 Name 속성이 있다면, 이 속성을 직접적으로 참조할 때 어느 테이블의 Name 속성인지 모호함이 발생할 수 있습니다. 이러한 모호성은 SQL이 쿼리를 해석하는 데 혼란을 주며, 잘못된 결과를 초래할 수도 있습니다.
2. 해결 방법: 테이블 이름을 통한 명확화 (Qualifying Attribute Names)
이러한 모호성을 해결하기 위해 속성 이름 앞에 테이블 이름을 명시적으로 추가하여 사용합니다. 테이블 이름과 속성 이름 사이에는 **점(.)**을 사용합니다. 예를 들어:
SELECT DEPARTMENT.Name, EMPLOYEE.Name FROM DEPARTMENT, EMPLOYEE
위와 같이 테이블 이름을 추가하면 SQL이 각 Name 속성이 어느 테이블에 속하는지 명확히 알 수 있습니다.
3. 예시
부서의 이름과 직원의 이름을 모두 조회하고 싶을 때, 아래와 같이 명확히 표기해야 합니다
SELECT DEPARTMENT.Name AS DepartmentName, EMPLOYEE.Name AS EmployeeName
FROM DEPARTMENT
JOIN EMPLOYEE
ON DEPARTMENT.Dnumber = EMPLOYEE.Dno;
여기서 DEPARTMENT.Name과 EMPLOYEE.Name은 서로 다른 테이블의 Name 속성을 의미합니다.
요약
- 속성 이름 중복 문제를 방지하기 위해 테이블 이름.속성 이름 형식을 사용하여 명확히 구분합니다.
- 테이블 이름을 사용하여 애매성을 해소하면, 쿼리 해석의 정확성과 가독성을 높일 수 있습니다.
이렇게 함으로써 SQL 쿼리에서 속성 이름이 겹쳐 발생하는 혼란을 피하고, 원하는 데이터를 정확히 조회할 수 있습니다.
Data Retrieval in SQL: Renaming Attribute
1. 테이블 이름에 별칭 부여하기
SQL 쿼리에서 테이블 이름이 길거나 반복해서 사용되는 경우, **별칭(Alias)**을 부여하여 코드의 간결함과 가독성을 높일 수 있습니다. AS 키워드를 사용하여 테이블 이름에 별칭을 설정할 수 있으며, 이후에는 별칭만으로 테이블을 참조할 수 있습니다.
예를 들어, EMPLOYEE 테이블을 E라는 별칭으로 지정하면 다음과 같이 작성할 수 있습니다:
SELECT E.Name, E.Salary
FROM EMPLOYEE AS E;
이렇게 하면 쿼리에서 EMPLOYEE 대신 E만으로 속성을 호출할 수 있어 코드가 간결해집니다.
2. 동일한 테이블에 대해 별칭을 사용할 때 (Self-Join)
동일한 테이블을 여러 번 참조해야 하는 Self-Join 같은 상황에서는 별칭이 매우 유용합니다. 예를 들어, 한 직원의 상사(슈퍼바이저) 정보를 조회하려면 EMPLOYEE 테이블을 두 번 참조해야 하는데, 이때 별칭을 사용해 명확하게 구분할 수 있습니다.
다음 쿼리는 직원과 그 직원의 상사 이름을 조회하는 예시입니다:
SELECT E.Name AS EmployeeName, S.Name AS SupervisorName
FROM EMPLOYEE AS E
JOIN EMPLOYEE AS S
ON E.Super_ssn = S.Ssn;
여기서 E는 직원(Employee)을 나타내고, S는 상사(Supervisor)를 나타냅니다. 이를 통해 EMPLOYEE 테이블을 두 번 참조하더라도 혼동을 피할 수 있습니다.
3. 속성 이름에 별칭 부여하기
SQL에서는 속성 이름에도 별칭을 부여할 수 있습니다. 속성의 별칭은 결과에서 해당 속성의 이름을 다른 이름으로 출력하고 싶을 때 사용됩니다. AS 키워드를 사용해 원하는 이름을 지정하면 됩니다.
예를 들어, 직원의 이름과 월급을 조회할 때 Salary 속성을 MonthlyIncome으로 표시하고 싶다면 다음과 같이 작성할 수 있습니다:
SELECT Name, Salary AS MonthlyIncome
FROM EMPLOYEE;
결과에서는 Salary 대신 MonthlyIncome이라는 열 이름이 표시됩니다.
요약
- 테이블 별칭(Alias): 긴 테이블 이름을 간단하게 지정하여 가독성을 높입니다.
- Self-Join에서의 별칭: 같은 테이블을 여러 번 참조할 때 별칭을 통해 혼란을 방지합니다.
- 속성 이름에 별칭 부여: 결과에서 속성 이름을 원하는 이름으로 바꿔 출력합니다.
Two More Features of SQL
1. WHERE 절이 없는 경우
SQL 쿼리에서 WHERE 절이 생략되면 특정 조건 없이 모든 튜플(레코드)을 조회하게 됩니다. 이는 FROM 절에 명시된 테이블의 모든 레코드를 가져오는 동작을 의미합니다.
SELECT * FROM EMPLOYEE;
위와 같이 WHERE 절을 생략하면 EMPLOYEE 테이블에 존재하는 모든 레코드가 조회됩니다.
여러 테이블이 있는 경우
여러 테이블이 FROM 절에 포함되었지만 WHERE 절에 결합 조건이 없다면, SQL은 모든 테이블의 가능한 모든 튜플 조합을 반환합니다. 이를 **카티션 곱(Cartesian Product)**이라 하며, 데이터가 많을 경우 예상보다 큰 결과가 나올 수 있으므로 WHERE 절을 사용하는 것이 좋습니다.
SELECT * FROM EMPLOYEE, DEPARTMENT;
이 쿼리는 EMPLOYEE 테이블과 DEPARTMENT 테이블의 모든 가능한 조합을 반환합니다. 따라서 JOIN 조건을 명확히 지정하지 않으면 큰 결과가 나올 수 있습니다.
2. 애스터리스크(*) 사용
SQL에서는 애스터리스크(*)를 사용하여 특정 속성을 나열하지 않고도 모든 속성을 한 번에 조회할 수 있습니다. 이는 모든 열을 조회하고 싶을 때 속성 이름을 일일이 나열하지 않아도 되어 간편합니다.
SELECT * FROM EMPLOYEE;
이렇게 하면 EMPLOYEE 테이블에 있는 모든 열의 데이터가 출력됩니다.
요약
- WHERE 절 생략: 조건 없이 테이블의 모든 레코드를 조회하거나, 다중 테이블 사용 시 카티션 곱을 생성합니다. 이를 통해 모든 데이터를 가져올 수 있지만, 결합 조건이 없으면 예상보다 큰 결과가 나올 수 있어 주의가 필요합니다.
- 애스터리스크(*) 사용: 모든 속성을 한 번에 조회할 때 사용하여, 간편하게 전체 데이터를 가져올 수 있습니다.
테이블을 JOIN 과 WHERE 절 모두 연결할 수 있는 것인가?
1. JOIN을 사용한 방법
JOIN 키워드를 사용하면 테이블을 연결할 때 보다 명확하고 직관적인 방식으로 쿼리를 작성할 수 있습니다. 각 테이블을 결합할 때 조건을 JOIN 절 내에서 지정하며, 다양한 JOIN 방식(내부 조인, 외부 조인 등)을 사용할 수 있습니다.
예시 (INNER JOIN)
다음은 EMPLOYEE 테이블과 DEPARTMENT 테이블을 Dnumber 속성을 통해 결합하는 예시입니다:
SELECT EMPLOYEE.Name, DEPARTMENT.Dname
FROM EMPLOYEE
JOIN DEPARTMENT
ON EMPLOYEE.Dnumber = DEPARTMENT.Dnumber;
- JOIN을 사용하여 두 테이블을 결합하고, ON 절에서 결합 조건을 지정합니다.
- 이 예시는 Dnumber 값이 일치하는 행만 조회하는 INNER JOIN입니다.
2. WHERE 절을 사용한 방법
JOIN 절을 사용하지 않고 WHERE 절에서 결합 조건을 직접 작성할 수도 있습니다. 이 방식은 SQL의 초창기 스타일로, 두 테이블을 나열한 후 WHERE 절에 결합 조건을 지정합니다.
예시 (WHERE 사용)
위 예시와 동일하게 EMPLOYEE와 DEPARTMENT를 결합하는 쿼리는 다음과 같이 작성할 수 있습니다:
SELECT EMPLOYEE.Name, DEPARTMENT.Dname
FROM EMPLOYEE, DEPARTMENT
HERE EMPLOYEE.Dnumber = DEPARTMENT.Dnumber;
- JOIN 키워드 없이 두 테이블을 나열하고, WHERE 절에서 결합 조건을 작성합니다.
- WHERE 절을 통해 결합하면 기본적으로 INNER JOIN과 같은 효과를 냅니다.
JOIN과 WHERE 절의 차이점
- 가독성: JOIN 구문을 사용하면 결합하려는 테이블과 조건이 명확하게 드러나므로 더 직관적이고 가독성이 좋습니다.
- 외부 조인 지원: LEFT JOIN, RIGHT JOIN 등 외부 조인(LEFT OUTER JOIN, RIGHT OUTER JOIN)은 JOIN 구문에서만 지원됩니다. WHERE 절만 사용해서는 외부 조인을 구현할 수 없습니다.
- 결과 해석: WHERE 절로 결합할 경우, 모든 테이블 간의 카티션 곱이 먼저 생성된 후 조건을 필터링합니다. 반면 JOIN은 결합된 테이블 간 조건을 바로 적용합니다.
Table as Sets
1. SQL에서 테이블은 기본적으로 Multiset(다중집합)
SQL은 테이블을 **집합(Set)**이 아닌 **Multiset(다중집합)**으로 취급합니다. 즉, 테이블 내에 동일한 값의 행이 여러 번 나타날 수 있습니다. 이는 수학적 집합과 달리 중복된 튜플(행)이 존재할 수 있다는 의미입니다.
중복 허용 이유
- 중복 제거는 비용이 많이 드는 연산이기 때문에 SQL은 기본적으로 중복 제거를 수행하지 않습니다.
- 사용자가 쿼리 결과에서 중복을 원하는 경우도 있어 SQL은 기본적으로 중복을 허용합니다.
- 집계 함수와 같은 연산에서는 중복된 값이 필요한 경우가 있습니다.
2. 중복 제거: DISTINCT 키워드
특정 쿼리에서 중복을 제거하고 고유한 값만 조회하고 싶다면 DISTINCT 키워드를 사용합니다.
예시
다음 쿼리는 모든 직원의 월급을 중복 없이 조회합니다:
SELECT DISTINCT Salary
FROM EMPLOYEE;
- DISTINCT를 사용하면 중복된 값이 제거되고 고유한 값만 반환됩니다.
- 기본적으로 SQL은 ALL 옵션을 사용하여 중복을 허용하므로, DISTINCT를 명시적으로 지정해야 중복이 제거됩니다.
3. SQL에서의 집합 연산
SQL은 집합 이론의 일부 연산을 지원합니다. 이 연산들은 두 테이블 간의 데이터를 결합하거나 차집합을 구할 때 유용하게 사용됩니다. SQL에서 제공하는 주요 집합 연산은 다음과 같습니다:
- UNION: 두 쿼리의 결과를 합집합으로 결합합니다. 중복된 값은 자동으로 제거됩니다.
- INTERSECT: 두 쿼리의 결과에서 공통된 튜플만 반환합니다.
- EXCEPT: 첫 번째 쿼리의 결과에서 두 번째 쿼리의 결과에 없는 튜플만 반환합니다.
예시
다음 예시는 PROJECT 테이블에서 특정 조건을 충족하는 프로젝트에 대해 Smith가 매니저로 있는 프로젝트와 Smith가 작업자로 있는 프로젝트의 공통 부분을 조회하는 방식입니다.
SELECT ProjectName FROM PROJECT WHERE Manager = 'Smith' INTERSECT
SELECT ProjectName FROM PROJECT WHERE Worker = 'Smith';
- 이 쿼리는 INTERSECT를 사용하여 Smith가 매니저이면서 동시에 작업자로 있는 프로젝트만 조회합니다.
4. 다중집합 연산
SQL에서는 UNION ALL, INTERSECT ALL, EXCEPT ALL과 같이 ALL 키워드를 추가하여 다중집합 연산도 지원합니다. ALL을 추가하면 중복을 제거하지 않고 모든 튜플을 포함합니다.
예시
- UNION ALL은 중복된 값도 포함하여 두 쿼리 결과를 모두 합칩니다.
- EXCEPT ALL은 첫 번째 쿼리 결과에서 두 번째 쿼리 결과에 없는 모든 튜플을 반환하는데, 중복도 그대로 유지됩니다.
요약
- SQL 테이블은 기본적으로 Multiset으로 처리되어 중복을 허용합니다.
- DISTINCT 키워드를 사용하면 쿼리 결과에서 중복을 제거할 수 있습니다.
- SQL에서는 집합 연산(UNION, INTERSECT, EXCEPT)을 제공하여 테이블 간의 합집합, 교집합, 차집합을 구할 수 있으며, ALL 키워드를 사용하여 중복을 포함한 다중집합 연산도 가능합니다.
'Data Enginnering > Database' 카테고리의 다른 글
[NoSQL] K-V / Document / Column / Graph Databases (0) | 2024.11.19 |
---|---|
[SQL] Nested Query, Join, Aggregate, Group, Order (1) | 2024.11.15 |
[SQL] Integrity Constraint, DDL vs DML (0) | 2024.11.07 |
[Data] DuckDB, Data Warehouse 종류, Data 관리를 위한 필수요소 (1) | 2024.11.06 |
[SQL] select, group by, count 사용하기 (3) | 2024.10.31 |