SELECT 예(Transact-SQL)

이 항목에서는 SELECT 문에 대한 사용 예를 보여 줍니다.

1.SELECT를 사용하여 행 및 열 검색

다음 예에서는 세 개의 코드 예를 보여 줍니다. 첫 번째 코드 예에서는 AdventureWorks2012 데이터베이스의 Product 테이블에서 모든 행(WHERE 절이 지정되지 않음) 및 모든 열(* 사용)을 반환합니다.

USE AdventureWorks2012;
GO
SELECT *
FROM Production.Product
ORDER BY Name ASC;
-- Alternate way.
USE AdventureWorks2012;
GO
SELECT p.*
FROM Production.Product AS p
ORDER BY Name ASC;
GO

다음 예에서는 AdventureWorks2012 데이터베이스의 Product 테이블에서 모든 행(WHERE 절이 지정되지 않음) 및 열의 하위 집합(Name, ProductNumber, ListPrice)을 반환합니다. 또한 열 머리글이 추가됩니다.

USE AdventureWorks2012;
GO
SELECT Name, ProductNumber, ListPrice AS Price
FROM Production.Product 
ORDER BY Name ASC;
GO

다음 예에서는 제품 라인이 R이고 제조에 필요한 기간이 4일보다 작은 Product에 대한 행만 반환합니다.

USE AdventureWorks2012;
GO
SELECT Name, ProductNumber, ListPrice AS Price
FROM Production.Product 
WHERE ProductLine = 'R' 
AND DaysToManufacture < 4
ORDER BY Name ASC;
GO

2.SELECT에 열 머리글 및 계산 사용

다음 예에서는 Product 테이블의 모든 행을 반환합니다. 첫 번째 예에서는 각 제품에 대한 총 판매액과 할인 판매액을 반환합니다. 두 번째 예에서는 각 제품에 대한 총 수익이 계산됩니다.

USE AdventureWorks2012;
GO
SELECT p.Name AS ProductName, 
NonDiscountSales = (OrderQty * UnitPrice),
Discounts = ((OrderQty * UnitPrice) * UnitPriceDiscount)
FROM Production.Product AS p 
INNER JOIN Sales.SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID 
ORDER BY ProductName DESC;
GO

다음 쿼리에서는 각 판매 주문의 각 제품에 대한 총 수익을 계산합니다.

USE AdventureWorks2012;
GO
SELECT 'Total income is', ((OrderQty * UnitPrice) * (1.0 - UnitPriceDiscount)), ' for ',
p.Name AS ProductName 
FROM Production.Product AS p 
INNER JOIN Sales.SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID 
ORDER BY ProductName ASC;
GO

3.SELECT에 DISTINCT 사용

다음 예에서는 DISTINCT를 사용하여 중복된 제목을 검색하지 않도록 합니다.

USE AdventureWorks2012;
GO
SELECT DISTINCT JobTitle
FROM HumanResources.Employee
ORDER BY JobTitle;
GO

4.SELECT INTO로 테이블 만들기

다음 첫 번째 예에서는 tempdb에 #Bicycles라는 임시 테이블을 만듭니다.

USE tempdb;
GO
IF OBJECT_ID (N'#Bicycles',N'U') IS NOT NULL
DROP TABLE #Bicycles;
GO
SELECT * 
INTO #Bicycles
FROM AdventureWorks2012.Production.Product
WHERE ProductNumber LIKE 'BK%';
GO

다음 두 번째 예에서는 영구 테이블 NewProducts를 만듭니다.

USE AdventureWorks2012;
GO
IF OBJECT_ID('dbo.NewProducts', 'U') IS NOT NULL
    DROP TABLE dbo.NewProducts;
GO
ALTER DATABASE AdventureWorks2012 SET RECOVERY BULK_LOGGED;
GO

SELECT * INTO dbo.NewProducts
FROM Production.Product
WHERE ListPrice > $25 
AND ListPrice < $100;
GO
ALTER DATABASE AdventureWorks2012 SET RECOVERY FULL;
GO

5.상관 하위 쿼리 사용

다음 예에서는 기능상 동일한 쿼리를 보여 주고 EXISTS 키워드와 IN 키워드를 사용할 때의 차이점에 대해 설명합니다. 두 예는 모두 제품 모델이 긴 팔 로고 셔츠이고 Product와 ProductModel 테이블 간에 ProductModelID가 일치하는 각 제품 이름의 인스턴스 하나를 검색하는 유효한 하위 쿼리입니다.

USE AdventureWorks2012;
GO
SELECT DISTINCT Name
FROM Production.Product AS p 
WHERE EXISTS
    (SELECT *
     FROM Production.ProductModel AS pm 
     WHERE p.ProductModelID = pm.ProductModelID
           AND pm.Name LIKE 'Long-Sleeve Logo Jersey%');
GO

-- OR

USE AdventureWorks2012;
GO
SELECT DISTINCT Name
FROM Production.Product
WHERE ProductModelID IN
    (SELECT ProductModelID 
     FROM Production.ProductModel
     WHERE Name LIKE 'Long-Sleeve Logo Jersey%');
GO

다음 예에서는 상관 또는 반복 하위 쿼리에 IN을 사용합니다. 이것은 외부 쿼리에 따라 해당 값이 달라지는 쿼리입니다. 이 쿼리는 외부 쿼리에서 선택한 각 행마다 한 번씩 반복적으로 실행됩니다. 이 쿼리는 SalesPerson 테이블에서 보너스가 5000.00이고 Employee 및 SalesPerson 테이블에서 직원 ID가 일치하는 각 직원의 이름 및 성의 인스턴스 하나를 검색합니다.

USE AdventureWorks2012;
GO
SELECT DISTINCT p.LastName, p.FirstName 
FROM Person.Person AS p 
JOIN HumanResources.Employee AS e
    ON e.BusinessEntityID = p.BusinessEntityID WHERE 5000.00 IN
    (SELECT Bonus
     FROM Sales.SalesPerson AS sp
     WHERE e.BusinessEntityID = sp.BusinessEntityID);
GO

이 문의 이전 하위 쿼리는 외부 쿼리와 독립적으로 평가할 수 없습니다. Employee.EmployeeID의 값이 필요하지만 이 값은 SQL Server 데이터베이스 엔진에서 Employee의 다른 행을 검사하는 경우 변경됩니다.

상관 하위 쿼리는 외부 쿼리의 HAVING 절에서도 사용할 수 있습니다. 다음 예에서는 최고 가격이 모델 평균 가격의 두 배 이상인 제품 모델을 찾습니다.

USE AdventureWorks2012;
GO
SELECT p1.ProductModelID
FROM Production.Product AS p1
GROUP BY p1.ProductModelID
HAVING MAX(p1.ListPrice) >= ALL
    (SELECT AVG(p2.ListPrice)
     FROM Production.Product AS p2
     WHERE p1.ProductModelID = p2.ProductModelID);
GO

다음 예에서는 두 개의 상관 하위 쿼리를 사용하여 특정 제품을 판매한 직원의 이름을 찾습니다.

USE AdventureWorks2012;
GO
SELECT DISTINCT pp.LastName, pp.FirstName 
FROM Person.Person pp JOIN HumanResources.Employee e
ON e.BusinessEntityID = pp.BusinessEntityID WHERE pp.BusinessEntityID IN 
(SELECT SalesPersonID 
FROM Sales.SalesOrderHeader
WHERE SalesOrderID IN 
(SELECT SalesOrderID 
FROM Sales.SalesOrderDetail
WHERE ProductID IN 
(SELECT ProductID 
FROM Production.Product p 
WHERE ProductNumber = 'BK-M68B-42')));
GO

6.GROUP BY 사용

다음 예에서는 데이터베이스에서 각 판매 주문의 합계를 구합니다.

USE AdventureWorks2012;
GO
SELECT SalesOrderID, SUM(LineTotal) AS SubTotal
FROM Sales.SalesOrderDetail
GROUP BY SalesOrderID
ORDER BY SalesOrderID;
GO

GROUP BY 절을 사용했으므로 각 판매 주문에 대해 모든 판매의 합계를 포함하는 한 행만 반환됩니다.

7.GROUP BY에 여러 그룹 사용

다음 예에서는 제품 ID 및 특별 행사 ID별로 그룹화된 평균 가격과 연간 판매액의 합계를 구합니다.

USE AdventureWorks2012;
GO
SELECT ProductID, SpecialOfferID, AVG(UnitPrice) AS [Average Price], 
    SUM(LineTotal) AS SubTotal
FROM Sales.SalesOrderDetail
GROUP BY ProductID, SpecialOfferID
ORDER BY ProductID;
GO

8.GROUP BY 및 WHERE 사용

다음 예에서는 가격이 $1000보다 큰 행만 검색한 후 그 결과를 그룹화합니다.

USE AdventureWorks2012;
GO
SELECT ProductModelID, AVG(ListPrice) AS [Average List Price]
FROM Production.Product
WHERE ListPrice > $1000
GROUP BY ProductModelID
ORDER BY ProductModelID;
GO

9.GROUP BY에 식 사용

다음 예에서는 식으로 그룹화를 수행합니다. 식에 집계 함수가 없는 경우 식으로 그룹화를 수행할 수 있습니다.

USE AdventureWorks2012;
GO
SELECT AVG(OrderQty) AS [Average Quantity], 
NonDiscountSales = (OrderQty * UnitPrice)
FROM Sales.SalesOrderDetail
GROUP BY (OrderQty * UnitPrice)
ORDER BY (OrderQty * UnitPrice) DESC;
GO

10.GROUP BY 및 ORDER BY 사용

다음 예에서는 각 제품 유형의 평균 가격을 찾아 그 결과를 평균 가격에 따라 정렬합니다.

USE AdventureWorks2012;
GO
SELECT ProductID, AVG(UnitPrice) AS [Average Price]
FROM Sales.SalesOrderDetail
WHERE OrderQty > 10
GROUP BY ProductID
ORDER BY AVG(UnitPrice);
GO

11.HAVING 절 사용

다음 첫 번째 예에서는 HAVING 절에 집계 함수를 사용합니다. SalesOrderDetail 테이블의 행을 제품 ID별로 그룹화하고 평균 주문 수량이 5개 이하인 제품을 제외시킵니다. 두 번째 예에서는 집계 함수 없이 HAVING 절을 사용합니다.

USE AdventureWorks2012;
GO
SELECT ProductID 
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING AVG(OrderQty) > 5
ORDER BY ProductID;
GO

다음 쿼리는 HAVING 절에서 LIKE 절을 사용합니다.

USE AdventureWorks2012 ;
GO
SELECT SalesOrderID, CarrierTrackingNumber 
FROM Sales.SalesOrderDetail
GROUP BY SalesOrderID, CarrierTrackingNumber
HAVING CarrierTrackingNumber LIKE '4BD%'
ORDER BY SalesOrderID ;
GO

12.HAVING 및 GROUP BY 사용

다음 예에서는 하나의 SELECT 문에 GROUP BY, HAVING, WHERE 및 ORDER BY 절을 사용합니다. 가격이 $25를 초과하는 제품과 평균 주문 수량이 5 미만인 제품을 제거한 후에 그룹과 요약 값을 생성합니다. 또한 결과를 ProductID별로 정렬합니다.

USE AdventureWorks2012;
GO
SELECT ProductID 
FROM Sales.SalesOrderDetail
WHERE UnitPrice < 25.00
GROUP BY ProductID
HAVING AVG(OrderQty) > 5
ORDER BY ProductID;
GO

13.SUM 및 AVG와 함께 HAVING 사용

다음 예에서는 SalesOrderDetail 테이블을 제품 ID별로 그룹화하며 총 주문액이 $1000000.00 이상이며 평균 주문 수량이 3 미만인 제품의 그룹만 포함합니다.

USE AdventureWorks2012;
GO
SELECT ProductID, AVG(OrderQty) AS AverageQuantity, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING SUM(LineTotal) > $1000000.00
AND AVG(OrderQty) < 3;
GO

총 판매액이 $2000000.00 이상인 제품을 보려면 다음 쿼리를 사용합니다.

USE AdventureWorks2012;
GO
SELECT ProductID, Total = SUM(LineTotal)
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING SUM(LineTotal) > $2000000.00;
GO

각 제품에 대한 계산에 최소 1500개 이상의 항목을 포함시키려는 경우 HAVING COUNT(*) > 1500을 사용하여 1500개 미만으로 판매된 항목에 대한 합계를 반환하는 제품은 제외시킬 수 있습니다. 다음 쿼리를 사용합니다.

USE AdventureWorks2012;
GO
SELECT ProductID, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING COUNT(*) > 1500;
GO

14.INDEX 최적화 프로그램 힌트 사용

다음 예에서는 INDEX 최적화 프로그램 힌트를 사용하는 두 가지 방법을 보여 줍니다. 첫 번째 예에서는 최적화 프로그램이 테이블에서 비클러스터형 인덱스를 사용하여 행을 검색하도록 하며 두 번째 예에서는 인덱스 0을 사용하여 테이블 검색을 수행하도록 합니다.

USE AdventureWorks2012;
GO
SELECT pp.FirstName, pp.LastName, e.NationalIDNumber
FROM HumanResources.Employee AS e WITH (INDEX(AK_Employee_NationalIDNumber))
JOIN Person.Person AS pp on e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO

-- Force a table scan by using INDEX = 0.
USE AdventureWorks2012;
GO
SELECT pp.LastName, pp.FirstName, e.JobTitle
FROM HumanResources.Employee AS e WITH (INDEX = 0) JOIN Person.Person AS pp
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO

13.OPTION 및 GROUP 힌트 사용

다음 예에서는 GROUP BY 절과 함께 OPTION (GROUP) 절을 사용하는 방법을 보여 줍니다.

USE AdventureWorks2012;
GO
SELECT ProductID, OrderQty, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
WHERE UnitPrice < $5.00
GROUP BY ProductID, OrderQty
ORDER BY ProductID, OrderQty
OPTION (HASH GROUP, FAST 10);
GO

15.UNION 쿼리 힌트 사용

다음 예에서는 MERGE UNION 쿼리 힌트를 사용합니다.

USE AdventureWorks2012;
GO
SELECT BusinessEntityID, JobTitle, HireDate, VacationHours, SickLeaveHours
FROM HumanResources.Employee AS e1
UNION
SELECT BusinessEntityID, JobTitle, HireDate, VacationHours, SickLeaveHours
FROM HumanResources.Employee AS e2
OPTION (MERGE UNION);
GO

16.단순 UNION 사용

다음 예에서는 결과 집합에 ProductModel 및 Gloves 테이블의 ProductModelID 및 Name 열의 내용이 포함됩니다.

USE AdventureWorks2012;
GO
IF OBJECT_ID ('dbo.Gloves', 'U') IS NOT NULL
DROP TABLE dbo.Gloves;
GO
-- Create Gloves table.
SELECT ProductModelID, Name
INTO dbo.Gloves
FROM Production.ProductModel
WHERE ProductModelID IN (3, 4);
GO

-- Here is the simple union.
USE AdventureWorks2012;
GO
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves
ORDER BY Name;
GO

17.UNION과 함께 SELECT INTO 사용

다음 예에서 두 번째 SELECT 문의 INTO 절은 ProductModel 및 Gloves 테이블의 지정된 열에 대해 UNION 연산을 수행한 마지막 결과 집합을 ProductResults 테이블에 포함시키도록 지정합니다. Gloves 테이블은 첫 번째 SELECT 문에서 생성됩니다.

USE AdventureWorks2012;
GO
IF OBJECT_ID ('dbo.ProductResults', 'U') IS NOT NULL
DROP TABLE dbo.ProductResults;
GO
IF OBJECT_ID ('dbo.Gloves', 'U') IS NOT NULL
DROP TABLE dbo.Gloves;
GO
-- Create Gloves table.
SELECT ProductModelID, Name
INTO dbo.Gloves
FROM Production.ProductModel
WHERE ProductModelID IN (3, 4);
GO

USE AdventureWorks2012;
GO
SELECT ProductModelID, Name
INTO dbo.ProductResults
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves;
GO

SELECT ProductModelID, Name 
FROM dbo.ProductResults;

18.두 SELECT 문에서 ORDER BY와 함께 UNION 사용

UNION 절과 함께 사용되는 특정 매개 변수의 순서는 중요합니다. 다음 예에서는 출력 시 이름이 바뀌는 열이 있는 두 SELECT 문에서 UNION을 잘못 사용한 경우와 올바르게 사용한 경우를 보여 줍니다.

USE AdventureWorks2012;
GO
IF OBJECT_ID ('dbo.Gloves', 'U') IS NOT NULL
DROP TABLE dbo.Gloves;
GO
-- Create Gloves table.
SELECT ProductModelID, Name
INTO dbo.Gloves
FROM Production.ProductModel
WHERE ProductModelID IN (3, 4);
GO

/* INCORRECT */
USE AdventureWorks2012;
GO
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
ORDER BY Name
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves;
GO

/* CORRECT */
USE AdventureWorks2012;
GO
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID NOT IN (3, 4)
UNION
SELECT ProductModelID, Name
FROM dbo.Gloves
ORDER BY Name;
GO

19.세 개의 SELECT 문에서 UNION을 사용하여 ALL 및 괄호의 효과 확인

다음 예에서는 UNION을 사용하여 동일한 5개의 데이터 행이 있는 세 테이블의 결과를 결합합니다. 첫 번째 예에서는 UNION ALL을 사용하여 중복 레코드를 보여 주고 15개 행을 모두 반환합니다. 두 번째 예에서는 ALL 없이 UNION을 사용하여 세 SELECT 문의 결합된 결과에서 중복 행을 제거하고 5개 행만 반환합니다.

세 번째 예에서는 첫 번째 UNION에서 ALL을 사용하고 ALL을 사용하지 않는 두 번째 UNION은 괄호로 묶습니다. 두 번째 UNION은 괄호로 묶었기 때문에 먼저 처리되고 ALL 옵션을 사용하지 않아 중복 행이 제거되기 때문에 5개 행을 반환합니다. 이러한 5개 행은 UNION ALL 키워드를 사용하여 첫 번째 SELECT 결과와 결합됩니다. 이 때 5개 행으로 된 두 집합 간의 중복 행은 제거되지 않습니다. 따라서 마지막 결과에는 10개의 행이 포함됩니다.

USE AdventureWorks2012;
GO
IF OBJECT_ID ('dbo.EmployeeOne', 'U') IS NOT NULL
DROP TABLE dbo.EmployeeOne;
GO
IF OBJECT_ID ('dbo.EmployeeTwo', 'U') IS NOT NULL
DROP TABLE dbo.EmployeeTwo;
GO
IF OBJECT_ID ('dbo.EmployeeThree', 'U') IS NOT NULL
DROP TABLE dbo.EmployeeThree;
GO

SELECT pp.LastName, pp.FirstName, e.JobTitle 
INTO dbo.EmployeeOne
FROM Person.Person AS pp JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO
SELECT pp.LastName, pp.FirstName, e.JobTitle 
INTO dbo.EmployeeTwo
FROM Person.Person AS pp JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO
SELECT pp.LastName, pp.FirstName, e.JobTitle 
INTO dbo.EmployeeThree
FROM Person.Person AS pp JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = pp.BusinessEntityID
WHERE LastName = 'Johnson';
GO
-- Union ALL
SELECT LastName, FirstName, JobTitle
FROM dbo.EmployeeOne
UNION ALL
SELECT LastName, FirstName ,JobTitle
FROM dbo.EmployeeTwo
UNION ALL
SELECT LastName, FirstName,JobTitle 
FROM dbo.EmployeeThree;
GO

SELECT LastName, FirstName,JobTitle
FROM dbo.EmployeeOne
UNION 
SELECT LastName, FirstName, JobTitle 
FROM dbo.EmployeeTwo
UNION 
SELECT LastName, FirstName, JobTitle 
FROM dbo.EmployeeThree;
GO

SELECT LastName, FirstName,JobTitle 
FROM dbo.EmployeeOne
UNION ALL
(
SELECT LastName, FirstName, JobTitle 
FROM dbo.EmployeeTwo
UNION
SELECT LastName, FirstName, JobTitle 
FROM dbo.EmployeeThree
);
GO

참고 항목

참조

CREATE TRIGGER(Transact-SQL)

CREATE VIEW(Transact-SQL)

DELETE(Transact-SQL)

EXECUTE(Transact-SQL)

식(Transact-SQL)

INSERT(Transact-SQL)

LIKE(Transact-SQL)

UNION(Transact-SQL)

EXCEPT 및 INTERSECT(Transact-SQL)

UPDATE(Transact-SQL)

WHERE(Transact-SQL)

PathName(Transact-SQL)

INTO 절(Transact-SQL)