SELECT (Transact-SQL)SELECT (Transact-SQL)

적용 대상: 예SQL Server 예Azure SQL Database 예Azure SQL Data Warehouse 예병렬 데이터 웨어하우스 APPLIES TO: yesSQL Server yesAzure SQL Database yesAzure SQL Data Warehouse yesParallel Data Warehouse

데이터베이스에서 행을 검색하고 SQL ServerSQL Server에서 하나 이상의 테이블에서 하나 이상의 행 또는 열을 선택할 수 있도록 합니다.Retrieves rows from the database and enables the selection of one or many rows or columns from one or many tables in SQL ServerSQL Server. SELECT 문의 전체 구문은 복잡하지만 주요 절은 다음과 같이 요약할 수 있습니다.The full syntax of the SELECT statement is complex, but the main clauses can be summarized as:

[ WITH { [ XMLNAMESPACES ,] [ <common_table_expression> ] } ][ WITH { [ XMLNAMESPACES ,] [ <common_table_expression> ] } ]

SELECT select_list [ INTO new_table ]SELECT select_list [ INTO new_table ]

[ FROM table_source ] [ WHERE search_condition ][ FROM table_source ] [ WHERE search_condition ]

[ GROUP BY group_by_expression ][ GROUP BY group_by_expression ]

[ HAVING search_condition ][ HAVING search_condition ]

[ ORDER BY order_expression [ ASC | DESC ] ][ ORDER BY order_expression [ ASC | DESC ] ]

UNION, EXCEPT 및 INTERSECT 연산자는 쿼리 간에 결과를 비교하거나 하나의 결과 집합으로 결합하는 데 사용됩니다.The UNION, EXCEPT, and INTERSECT operators can be used between queries to combine or compare their results into one result set.

항목 링크 아이콘 Transact-SQL 구문 규칙Topic link icon Transact-SQL Syntax Conventions

구문Syntax

-- Syntax for SQL Server and Azure SQL Database  
  
<SELECT statement> ::=    
    [ WITH { [ XMLNAMESPACES ,] [ <common_table_expression> [,...n] ] } ]  
    <query_expression>   
    [ ORDER BY { order_by_expression | column_position [ ASC | DESC ] }   
  [ ,...n ] ]   
    [ <FOR Clause>]   
    [ OPTION ( <query_hint> [ ,...n ] ) ]   
<query_expression> ::=   
    { <query_specification> | ( <query_expression> ) }   
    [  { UNION [ ALL ] | EXCEPT | INTERSECT }  
        <query_specification> | ( <query_expression> ) [...n ] ]   
<query_specification> ::=   
SELECT [ ALL | DISTINCT ]   
    [TOP ( expression ) [PERCENT] [ WITH TIES ] ]   
    < select_list >   
    [ INTO new_table ]   
    [ FROM { <table_source> } [ ,...n ] ]   
    [ WHERE <search_condition> ]   
    [ <GROUP BY> ]   
    [ HAVING < search_condition > ]   
-- Syntax for Azure SQL Data Warehouse and Parallel Data Warehouse  
  
[ WITH <common_table_expression> [ ,...n ] ]  
SELECT <select_criteria>  
[;]  
  
<select_criteria> ::=  
    [ TOP ( top_expression ) ]   
    [ ALL | DISTINCT ]   
    { * | column_name | expression } [ ,...n ]   
    [ FROM { table_source } [ ,...n ] ]  
    [ WHERE <search_condition> ]   
    [ GROUP BY <group_by_clause> ]   
    [ HAVING <search_condition> ]   
    [ ORDER BY <order_by_expression> ]  
    [ OPTION ( <query_option> [ ,...n ] ) ]  
  

RemarksRemarks

SELECT 문은 복잡하기 때문에 자세한 구문 요소와 인수가 다음과 같은 절로 표시됩니다.Because of the complexity of the SELECT statement, detailed syntax elements and arguments are shown by clause:

WITH XMLNAMESPACESWITH XMLNAMESPACES

WITH common_table_expressionWITH common_table_expression
HAVINGHAVING
SELECT 절SELECT Clause UNIONUNION
INTO 절INTO Clause EXCEPT 및 INTERSECTEXCEPT and INTERSECT
FROMFROM ORDER BYORDER BY
WHEREWHERE FOR 절FOR Clause
GROUP BYGROUP BY OPTION 절OPTION Clause

SELECT 문에서 절의 순서는 매우 중요합니다.The order of the clauses in the SELECT statement is significant. 선택 사항인 절은 생략할 수 있지만 이러한 절을 사용할 때는 적절한 순서로 표시해야 합니다.Any one of the optional clauses can be omitted, but when the optional clauses are used, they must appear in the appropriate order.

사용자 정의 함수 내의 SELECT 문은 함수에서 로컬인 변수에 값을 할당하는 식이 문의 선택 목록에 포함된 경우에만 허용됩니다.SELECT statements are permitted in user-defined functions only if the select lists of these statements contain expressions that assign values to variables that are local to the functions.

서버 이름 부분에 OPENDATASOURCE 함수를 사용하여 네 부분으로 구성한 이름은 SELECT 문에서 테이블 이름이 표시될 수 있는 곳이면 어디든 테이블 원본으로 사용할 수 있습니다.A four-part name constructed with the OPENDATASOURCE function as the server-name part can be used as a table source wherever a table name can appear in a SELECT statement. Azure SQL 데이터베이스Azure SQL Database에는 네 부분으로 된 이름을 지정할 수 없습니다.A four-part name cannot be specified for Azure SQL 데이터베이스Azure SQL Database.

SELECT 문에는 원격 테이블과 관련된 몇몇 구문 제한이 적용됩니다.Some syntax restrictions apply to SELECT statements that involve remote tables.

SELECT 문의 논리적 처리 순서Logical Processing Order of the SELECT statement

다음 단계에서는 SELECT 문의 논리적 처리 순서(바인딩 순서)를 보여 줍니다.The following steps show the logical processing order, or binding order, for a SELECT statement. 이 순서에 따라 특정 단계에서 정의한 개체를 후속 단계의 절에 사용할 수 있는 시기가 결정됩니다.This order determines when the objects defined in one step are made available to the clauses in subsequent steps. 예를 들어 쿼리 프로세스가 FROM 절에 정의된 테이블 또는 뷰에 바인딩(액세스)할 수 있는 경우 이러한 개체 및 해당 열을 모든 후속 단계에서 사용할 수 있습니다.For example, if the query processor can bind to (access) the tables or views defined in the FROM clause, these objects and their columns are made available to all subsequent steps. 반면, SELECT 절은 8단계이므로 해당 절에서 정의된 열 별칭 또는 파생 열을 이전 절에서 참조할 수는 없습니다.Conversely, because the SELECT clause is step 8, any column aliases or derived columns defined in that clause cannot be referenced by preceding clauses. 그러나 ORDER BY 절 등의 후속 절에서는 이러한 항목을 참조할 수 있습니다.However, they can be referenced by subsequent clauses such as the ORDER BY clause. 문의 실제 실행은 쿼리 프로세서를 통해 결정되며 순서는 이 목록과 다를 수 있습니다.The actual physical execution of the statement is determined by the query processor and the order may vary from this list.

  1. FROMFROM
  2. ONON
  3. JOINJOIN
  4. WHEREWHERE
  5. GROUP BYGROUP BY
  6. WITH CUBE 또는 WITH ROLLUPWITH CUBE or WITH ROLLUP
  7. HAVINGHAVING
  8. SELECTSELECT
  9. DISTINCTDISTINCT
  10. ORDER BYORDER BY
  11. 맨 위로 이동TOP

경고

위의 순서는 일반적으로 맞습니다.The preceding sequence is usually true. 그러나 순서가 달라지는 특수한 경우가 있을 수 있습니다.However, there are uncommon cases where the sequence may differ.

예를 들어 뷰에 클라스터형 인덱스가 있고 이 뷰가 일부 테이블 행을 제외하며 이 뷰의 SELECT 열 목록에서 varchar 데이터 형식을 정수로 바꾸는 CONVERT를 사용한다고 가정해 봅니다.For example, suppose you have a clustered index on a view, and the view excludes some table rows, and the view's SELECT column list uses a CONVERT that changes a data type from varchar to integer. 이런 상황에서 CONVERT는 WHERE 문이 실행되기 전에 실행될 수 있습니다.In this situation, the CONVERT may execute before the WHERE clause executes. 물론 일반적이지 않습니다.Uncommon indeed. 필요한 상황에서 다른 순서를 방지하기 위해 뷰를 수정하는 방법이 있는 경우가 종종 있습니다.Often there is a way to modify your view to avoid the different sequence, if it matters in your case.

사용 권한Permissions

데이터를 선택하려면 테이블이나 뷰에 대한 SELECT 권한이 있어야 합니다. 이 권한은 스키마에 대한 SELECT 권한이나 테이블에 대한 CONTROL 권한과 같은 상위 범위에서 상속할 수 있습니다.Selecting data requires SELECT permission on the table or view, which could be inherited from a higher scope such as SELECT permission on the schema or CONTROL permission on the table. 또는 db_datareader 또는 db_owner 고정 데이터베이스 역할이거나 sysadmin 고정 서버 역할의 멤버 자격이 필요합니다.Or requires membership in the db_datareader or db_owner fixed database roles, or the sysadmin fixed server role. SELECTINTO를 사용하여 새 테이블을 만들려면 CREATETABLE 권한과 새 테이블을 소유하는 스키마에 대한 ALTERSCHEMA 권한이 둘 다 있어야 합니다.Creating a new table using SELECTINTO also requires both the CREATETABLE permission, and the ALTERSCHEMA permission on the schema that owns the new table.

예:Examples:

다음 예에서는 AdventureWorksPDW2012AdventureWorksPDW2012 데이터베이스를 사용합니다.The following examples use the AdventureWorksPDW2012AdventureWorksPDW2012 database.

1.A. SELECT를 사용하여 행 및 열 검색Using SELECT to retrieve rows and columns

이 섹션에서는 세 가지 코드 예를 보여 줍니다.This section shows three code examples. 첫 번째 코드 예에서는 DimEmployee 테이블에서 모든 행(WHERE 절이 지정되지 않음) 및 모든 열(* 사용)을 반환합니다.This first code example returns all rows (no WHERE clause is specified) and all columns (using the *) from the DimEmployee table.

SELECT *  
FROM DimEmployee  
ORDER BY LastName;  

이 다음 예제에서는 테이블 별칭을 사용하여 같은 결과를 냅니다.This next example using table aliasing to achieve the same result.

SELECT e.*  
FROM DimEmployee AS e  
ORDER BY LastName;  

다음 예에서는 AdventureWorksPDW2012 데이터베이스의 DimEmployee 테이블에서 모든 행(WHERE 절이 지정되지 않음) 및 열의 하위 집합(FirstName, LastName, StartDate)을 반환합니다.This example returns all rows (no WHERE clause is specified) and a subset of the columns (FirstName, LastName, StartDate) from the DimEmployee table in the AdventureWorksPDW2012 database. 세 번째 열 머리글 이름이 FirstDay로 변경됩니다.The third column heading is renamed to FirstDay.

SELECT FirstName, LastName, StartDate AS FirstDay  
FROM DimEmployee   
ORDER BY LastName;  

이 예제에서는 EndDate가 NULL이 아니며 MaritalStatus가 'M'(기혼)인 DimEmployee의 행만 반환합니다.This example returns only the rows for DimEmployee that have an EndDate that is not NULL and a MaritalStatus of 'M' (married).

SELECT FirstName, LastName, StartDate AS FirstDay  
FROM DimEmployee   
WHERE EndDate IS NOT NULL   
AND MaritalStatus = 'M'  
ORDER BY LastName;  

2.B. SELECT에 열 머리글 및 계산 사용Using SELECT with column headings and calculations

다음 예제에서는 DimEmployee 테이블의 모든 행을 반환하며 BaseRate 및 40시간 근무 주를 기준으로 각 직원의 총 급여를 계산합니다.The following example returns all rows from the DimEmployee table, and calculates the gross pay for each employee based on their BaseRate and a 40-hour work week.

SELECT FirstName, LastName, BaseRate, BaseRate * 40 AS GrossPay  
FROM DimEmployee  
ORDER BY LastName;  

C.C. SELECT에 DISTINCT 사용Using DISTINCT with SELECT

다음 예제에서는 DISTINCT를 사용하여 DimEmployee 테이블의 모든 고유한 이름 목록을 생성합니다.The following example uses DISTINCT to generate a list of all unique titles in the DimEmployee table.

SELECT DISTINCT Title  
FROM DimEmployee  
ORDER BY Title;  

D.D. GROUP BY 사용Using GROUP BY

다음 예제에서는 일별 총 판매액을 모두 찾습니다.The following example finds the total amount for all sales on each day.

SELECT OrderDateKey, SUM(SalesAmount) AS TotalSales  
FROM FactInternetSales  
GROUP BY OrderDateKey  
ORDER BY OrderDateKey;  

GROUP BY 절을 사용했으므로 각 날짜에 대해 모든 판매의 합계를 포함하는 한 행만 반환됩니다.Because of the GROUP BY clause, only one row containing the sum of all sales is returned for each day.

E.E. GROUP BY에 여러 그룹 사용Using GROUP BY with multiple groups

다음 예제에서는 주문일과 프로모션 키별로 그룹화된 일별 총 인터넷 판매 합계와 평균 금액을 찾습니다.The following example finds the average price and the sum of Internet sales for each day, grouped by order date and the promotion key.


SELECT OrderDateKey, PromotionKey, AVG(SalesAmount) AS AvgSales, SUM(SalesAmount) AS TotalSales  
FROM FactInternetSales  
GROUP BY OrderDateKey, PromotionKey  
ORDER BY OrderDateKey;   

F.F. GROUP BY 및 WHERE 사용Using GROUP BY and WHERE

다음 예에서는 가격이 주문일이 2002년 8월 1일 이후인 행만 검색한 후 그 결과를 그룹화합니다.The following example puts the results into groups after retrieving only the rows with order dates later than August 1, 2002.

SELECT OrderDateKey, SUM(SalesAmount) AS TotalSales  
FROM FactInternetSales  
WHERE OrderDateKey > '20020801'  
GROUP BY OrderDateKey  
ORDER BY OrderDateKey;  

G.G. GROUP BY에 식 사용Using GROUP BY with an expression

다음 예에서는 식으로 그룹화를 수행합니다.The following example groups by an expression. 식에 집계 함수가 없는 경우 식으로 그룹화를 수행할 수 있습니다.You can group by an expression if the expression does not include aggregate functions.

SELECT SUM(SalesAmount) AS TotalSales  
FROM FactInternetSales  
GROUP BY (OrderDateKey * 10);  

H.H. GROUP BY 및 ORDER BY 사용Using GROUP BY with ORDER BY

다음 예제에서는 일별 판매 합계와 일별 주문을 찾습니다.The following example finds the sum of sales per day, and orders by the day.

SELECT OrderDateKey, SUM(SalesAmount) AS TotalSales  
FROM FactInternetSales  
GROUP BY OrderDateKey  
ORDER BY OrderDateKey;  

9.I. HAVING 절 사용Using the HAVING clause

이 쿼리에서는 HAVING 절을 사용하여 결과를 제한합니다.This query uses the HAVING clause to restrict results.

SELECT OrderDateKey, SUM(SalesAmount) AS TotalSales  
FROM FactInternetSales  
GROUP BY OrderDateKey  
HAVING OrderDateKey > 20010000  
ORDER BY OrderDateKey;  

참고 항목See Also

SELECT Examples (Transact-SQL)SELECT Examples (Transact-SQL)
힌트 (Transact-SQL)Hints (Transact-SQL)