SQL 쿼리 튜닝 팁

1. SELECT * ... 문장은 피하세요. 

쿼리의 결과로 모든 필드의 결과가 필요한 경우가 아니라면 SELECT리스트에 필요 한 필드들을 일일이 적어 주어야 합니다. 즉, "SELECT * From Table" 과 같은 쿼 리는 "SELECT Field1, Field2 From Table ..."과 같이 필요한 필드를 밝힌 쿼리로 작성하기 바랍니다. 


2. 알맞은 인덱스를 구성해서 쿼리가 인덱스를 타게 하세요

(효율적으로 인덱스를 구성하고 사용한다면 쿼리의 속도를, 그리고 궁극적으로는 DB 서버의 퍼포먼스를 놀라울 정도로 향상시킬 수 있습니다.)


3. 쿼리가 여러 번 DB서버에 들어가지 않게 하세요

만일 웹 서버가 DB 서버에 데이터를 요청할 때 저장 프로시저를 사용하지 않고 웹 서버에서 작성한 쿼리를 DB서버에 보내는 방식이라면, 되도록 쿼리가 DB서버에 자주 들어가지 않도록 작성하기 바랍니다. ex. 루프 내에서 단순한 SELECT쿼리를 계속 부르는 실수입니다. 이러한 경우에는 필요한 데이터를 모두 SELECT해서 가져온 다음에 레코드셋을 가지고 루프 연산을 수행하는 것이 좋습니다. ex. UPDATE 쿼리를 사용할 때 종종 실수를 하는 일이 있습니다. 어떤 값을 하나 증가시키기 위해 해당 값을 일단 SELECT 해 와서 그 값을 하나 증가시킨 뒤에 데 이터를 업데이트하는 경우가 있습니다. 이런 경우에는 당연히 "UPDATE Table SET Field = Field + 1 WHERE ..."와 같 은 쿼리로 해당 값을 SELECT하지 말고 한번의 UPDATE쿼리로 처리하는 것이 좋 습니다. ex. 서브쿼리가 있다는 것을 인식하지 못하는 데서 일어나는 실수도 있습니다. (즉, SELECT쿼리를 통해서 데이터를 반환 받고 반환 받은 값을 변환한 다음, INSERT쿼리를 통해서 변환한 값을 다른 테이블에 넣는 경우가 이러한 예에 해당합 니다.)


4. JOIN쿼리에서 사용 메모리를 줄이는 방법을 생각하세요. 

기본적으로 JOIN (여기에서는 Inner Join)을 사용하면 ON 절에 밝힌 조건에 의해 서 데이터를 추린 다음 WHERE 절 조건을 적용합니다. 따라서 ON 절 조건에 의해 추려지는 데이터는 메모리에 설정됩니다. 이때 아예 JOIN을 피할 수 있도록 테이블을 구성할 수 있다면 그렇게 하는 것이 가 장 좋은 방법이겠지만, 그렇게 할 수 없다면 되도록 JOIN 할 때 설정되는 임시 메 모리의 크기가 작게 만들어지도록 두 테이블에서 값은 같지만 메모리는 더 작게 차 지하는 필드를 찾아 그것을 ON조건에 사용하는 것이 유리합니다. 


5. SELECT가 많다면 NOLOCK 힌트를 줄 수도 있어요. 

( NOLOCK이란 DB서버 내부적으로 해당 데이터를 읽고 있음을 표시해 주는 LOCK을 설정하지 않는 것을 의미합니다.) 서비스 내용 구성상 SELECT 쿼리는 자주 일어나는데 INSERT나 UPDATE쿼리는 거의 일어나지 않는 환경이라면 "SELECT Field1 FROM Table (NOLOCK) ..."과 같이 NOLOCK 힌트를 주면 좋습 니다. 참고로 NOLOCK힌트의 단점은 NOLOCK을 쓰게 되면 변화된 데이터 내용을 반영 하지 않거나, 데이터가 변경 중이라도 데이터를 읽어 오는 현상이 일어날 수 있기 때문에 사용상의 주의가 요구됩니다. 다이내믹 타입의 레코드셋을 사용하는 것과 같이 변경된 값이 바로 반영되어야 하는 환경이 아니라면 크게 문제 되지는 않을 것 이지만요.


6. TOP을 이용해서 필요한 만큼만 부르세요. 

"SELECT * ..."가 불필요한 데이터까지 다 반환하는 좋지 못한 예였다면, TOP을 사용하지 않아서 필요도 없는 데이터 행(Row)까지 반환하는 것도 비슷한 맥락에서 퍼포먼스를 저하시키는 예라고 할 수 있습니다. 예를 들어 서비스의 한 웹 페이지에 게시판 목록을 보여주는 기능, 즉 어떤 자료에 대한 리스트를 10개 보여 주고 다음 페이지로 넘어가면 다음 리스트 10개를 보여 주는 페이지를 작성한다고 합시다. 그러면 처음 웹 페이지를 구성하는 데에 필요한 데이터는 10개인데도 불구하고 모든 데이터 행을 다 SELECT해 온 다음, 웹 스크 립트에서 루프를 10번 돌리면서 페이지를 꾸미는 경우를 자주 보았습니다. 이렇게 하면 리스트 페이지를 하나씩 넘어갈 때마다 전체 데이터가 반환되므로 네트워크 부하는 물론이고 웹 서버와 DB 서버의 메모리 부하도 커지게 되므로 결코 좋은 방 법이라고 할 수 없습니다. 이런 경우에는 "SELECT TOP n ..."과 같이 TOP을 써서 필요한 수만큼 데이터를 반환하도록 해 줍니다. 


7. 빠른 데이터 개수 반환 팁을 쓰세요. 

테이블에 저장되어 있는 데이터의 총 개수를 알아내기 위해서 "SELECT COUNT (PromaryKeyField) ..." 혹은 "SELECT COUNT(*) ..."와 같이 COUNT함수를 사용하는 경우가 있습니다. 이것이 잘못되 었다는 말이 아니고 만일 테이블에 있는 데이터 행의 총 개수를 알아내고자 하는 경 우라면 "SELECT rows FROM sysindexes WHERE id = OBJECT_ID('Table이름') AND indid <2" 의 쿼리를 사용하는 편이 속도가 훨씬 빠르다는 것입니다. (총 개수를 구하고자 할 때 사용하며, 일부 개수를 구할 수는 없습니다.)


8. 뷰나 스토어드 프로시져를 사용하세요. 

긴 쿼리문을 네트웍으로 전송하는것에 비해 뷰나 스토어드 프로시져는 그 이름만 전송하기 때문에(파라미터가 있다면 이것도 포함) 네트웍 트래픽을 감소시킬 수 있 습니다.. 게다가 보안관리까지 할 수 있기 때문에 여러분이 사용자에게 숨겨야하는 컬럼의 액세스 제한을 할 수 있습니다. 


9. 가능한 한 SQL Server 커서의 사용을 피하세요. 

SQL Server 커서는 select문에 비해 성능상에 좋지 않습니다.. 행 단위의 처리가 필요하다면 상관질의나 유도된 테이블을 사용하도록 노력해보세요. 


10. 트리거 대신에 제약조건을 사용하세요. 

제약조건은 트리거보다 성능면에서 훨씬 효율적입니다. 따라서 가능한 한 제약조건 을 사용하세요. 


11. 임시테이블 대신 테이블 변수를 사용하세요. 

테이블 변수는 임시테이블에 비해 잠금과 로깅 작업에 적은 리소스가 소모됩니다.. 따라서 가능한 한 테이블 변수를 사용하세요.


12. HAVING절의 사용은 피하세요. 

Having절은 GROUP BY에 의한 결과를 제한할 때 사용합니다.. GROUP BY에 Having절을 사용하였을 경우 GROUP BY에 의해서 결과들을 모두 집계한 다음 Having절에 명시한 조건으로 맞지 않는 결과를 버리게 됩니다.. 대부분의 경우 Having절의 필요 없이 GROUP BY와 Where절만으로 원하는 결과를 얻을 수 있습 니다.. 


13. 가능한 한 DISTINCT 문의 사용을 피하세요. 

DISTINCT문을 사용할 경우 소트에 따른 성능 하락이 있기 때문에 꼭 필요한 경우 에만 사용하세요. 


14. 결과에 적용된 행의 갯수를 표시하지 않아도 된다면 프로시져에 SET NOCOUNT ON을 추가해보세요. 

몇개의 행이 적용되었는지가 전달되지 않기 때문에 네트웍 트래픽이 감소합니다. 


15. 가능한 한 UNION 대신에 UNION ALL을 사용하세요. 

UNION ALL이 UNION보다 훨씬 빠릅니다.. 왜냐하면 UNION ALL은 로우의 중복 검사를 하지않는 반면에 UNION은 중복행이 있건 없건간에 중복검사를 수행하기 때문입니다.


16. SELECT * FROM TBL WHERE IDX LIKE '%A%'를하면 인덱스가 깨집니다.

17. INNER JOIN과 LEFT OUTER JOIN의 성능이 비슷하다고 생각될경우 INNER JOIN이 성능이 더 우수합니다.


출처: https://www.slideshare.net/ETRIBE_STG/sql-37344670

'SQL > SQL 튜닝' 카테고리의 다른 글

클러스터인덱스와 넌클러스터인덱스  (0) 2017.10.24
Nested Loop, Sort Merge, Hash JOIN  (0) 2017.10.23
옵티마이저 이해하기 - 1  (0) 2017.10.23
INDEX 튜닝  (0) 2017.10.23
쿼리실행순서  (0) 2017.09.01

Table변수

Table변수는 Meory상에 일시적으로 생성되는 Table로 Query가 실행되는 Session안에서만 유효하며 일반 변수와 같습니다. 또한 Table변수는 Primary Key, Null, Check 이 세가지 제약조건만 허락하며 Table변수선언시 사용자 데이터형식은 사용할 수 없습니다.

주의하실 점은 Table변수를 사용하려면 먼저 생성되어 있어야 한다는 것입니다.


1
2
3
4
5
Declare @Temp2 Table(
 ScrapReasonID Smallint,
 Name   nVarchar(50),
 ModifiedDate DateTime
)
cs

따라서 다음과 같이 임시Table을 사용할때 처럼 Table변수를 생성하는건 불가능합니다.

1
2
3
Select *
Into @Temp2
From Production.ScrapReason
cs


Table변수는 반드시 미리 생성되어 있어야 합니다.

위 예제Query를 보시면 Create Table대신에 Declare가 사용되었습니다. Table 변수는 말그대로 변수이기 때문에 변수를 선언할때와 마찬가지로 Declare가 사용되는 것입니다.
또한 Table변수는 Table이름의 맨앞에 @문자가 선행되어야 합니다.

1
2
3
Insert Into @Temp2
Select *
From Production.ScrapReason
cs


위에서 생성한 Table변수에 Production.ScrapReason Table의 내용을 담습니다.

1
Select * From @Temp2
cs

Table변수을 조회합니다.


위와 같이 Table변수의 생성, 저장, 조회하는 일련의 작업과정은 Query가 실행되는 Session안에서 한단위로 이루어 져야 합니다. 예를 들어 Table변수을 생성하는 부분과 Table변수에 데이터를 저장하는 부분을 별도의 Session안에서 실행하려고 하면 오류를 일으키게 되는 것입니다.

참고:

보통의 경우 성능향상을 위해서는 임시Table보다는 Table변수가 더 유리합니다. 또한 SQL Server에 Disk관련 I/O가 많아 성능상에 Issue가 발생했을 경우 Table변수를 활용하면 이 문제를 어느정도 해소할 수 있습니다. 단 Table변수는 Memory상에 배치되고 실행되는 것이므로 Memory자원을 더 많이 잡아먹는 단점이 있습니다.


따라서 분명 임시Table이나 변수Table은 용도에 따라 각각의 이점이 있을 것입니다. 따라서 맹목적으로 Table변수를 고집할 필요는 없습니다. 난해한 표현이지만 상황에 맞게 가장 적절한 대안을 찾으시길 바랍니다.


출처: http://lab.cliel.com/entry/SQL-임시-Table과-변수-Table [CLIEL LAB]

'SQL > MS-SQL' 카테고리의 다른 글

제약 조건(Constraint) #2 (기존 테이블에 추가/삭제)  (0) 2017.09.20
제약 조건(Constraint) #1 (의미와 설정)  (0) 2017.09.20
테이블 컬럼변경  (0) 2017.09.20
SELF JOIN  (0) 2017.09.19
join Diagram  (0) 2017.09.19

컬럼의 추가

ALTER TABLE 테이블명 ADD 추가할컬럼명 데이터형(데이터크기) 컬럼속성 


ALTER TABLE [TABLE명] ADD [컬럼명] CHAR(1) NOT NULL DEFAULT 'N'

ALTER TABLE [TABLE명] ADD [컬럼명] CHAR(1) NULL

컬럼변경

ALTER TABLE [TABLE명] ALTER COLUMN [컬럼명] [컬럼자료형] NULL(NOT NULL)

칼럼 삭제 

ALTER TABLE [TABLE명] DROP COLUMN [컬럼명]

기본키 추가 삭제

ALTER TABLE [TABLE명] DROP PRIMARY KEY;   -- 기본키를 지워준다.

ALTER TABLE [TABLE명] ADD CONSTRAINT [PK명] PRIMARY KEY ([KEY1],[KEY2],[...]);   -- PK를 생성한다.


'SQL > MS-SQL' 카테고리의 다른 글

제약 조건(Constraint) #1 (의미와 설정)  (0) 2017.09.20
테이블변수  (0) 2017.09.20
SELF JOIN  (0) 2017.09.19
join Diagram  (0) 2017.09.19
LEFT OUTER JOIN / WHERE  (0) 2017.09.19

SELF JOIN

자기 자신과 JOIN하는 것을 말한다. 예를들어 테이블에는 직속상관, 직속부서 코드만 존재한다고 할때, 직속상관, 직속부서에 대한 정보를 알고싶을때 사용한다. 그리고 누적합을 구할때에도 쓰인다.

 

1
2
3
4
SELECT *
  FROM TABLE T1
  LEFT OUTER JOIN TABLE T2 ON T1.PK = T2.PK 
                          AND T1.컬럼 = T2.현재부서컬럼
cs


여기서 T1이 가준테이블(자식테이블) T2가 부모테이블이 된다.
기준테이블에 부모테이블 컬럼이 추가되어 옆으로 붙는다고 생각하면 된다.

생각하는 관점을 기준테이블에서 생각해야한다.

누적합

예를들어서 일별로 값을 가지고있는 테이블이 있다고 가정하자



이 테이블을 월단위로 누적합을 구하고, 소계를 구하고, 테이블 전체의 총계를 구해보자.


우선 셀프조인을 사용하여 자신보다 큰 DATE를 가진 행을 JOIN시킨다. (여기서 주의할점은 자기보다 큰 행이면서 월이 같은 행이여야한다.) 


그리고 나중에 정렬을 위해서 SORT 컬럼을 만들어주면 

이렇게 하면 누적합을 구한 첫번째 행들이 만들어진다.

그리고 총계를 구하고 SORT를 걸면

다음과 같다.


코드






'SQL > MS-SQL' 카테고리의 다른 글

테이블변수  (0) 2017.09.20
테이블 컬럼변경  (0) 2017.09.20
join Diagram  (0) 2017.09.19
LEFT OUTER JOIN / WHERE  (0) 2017.09.19
NULL 비교하기  (0) 2017.09.19


'SQL > MS-SQL' 카테고리의 다른 글

테이블 컬럼변경  (0) 2017.09.20
SELF JOIN  (0) 2017.09.19
LEFT OUTER JOIN / WHERE  (0) 2017.09.19
NULL 비교하기  (0) 2017.09.19
일반집계함수 WINDOW FUNCTION  (0) 2017.09.07

규칙 

LEFT OUTER JOIN 시 ON 절에서는 우측(널값으로 채워지는 쪽)의 추가 제약조건을 넣고 

좌측의 추가 제약조건은 WHERE절에 넣어야 한다. 


1. 원하는 결과값 

1
2
3
4
5
SELECT *  --(184개 행 적용됨)
 FROM TBHZM200 AS A 
 LEFT OUTER JOIN MST_TKT_STA_STOCK AS B ON  a.Extn_Sta_No = b.Extn_Sta_No   
                                        AND B.Oper_DT = '20090713' -- 우측의 추가 제약조건
WHERE A.Transp_Oper_Org_CD = '1' -- 좌측의 추가제약조건
cs

2. 잘못된 예 -- INNER JOIN의 결과가 나오게 됨.

1
2
3
4
5
SELECT *  --(176개 행 적용됨)
 FROM TBHZM200 AS A 
 LEFT OUTER JOIN MST_TKT_STA_STOCK AS B ON  a.Extn_Sta_No = b.Extn_Sta_No   
                                       AND  A.Transp_Oper_Org_CD = '1'  
WHERE b.Oper_DT = '20090713'    
cs


3. 잘못된 예 

1
2
3
4
5
 SELECT * --(503개 행 적용됨) 
 FROM TBHZM200 AS A 
 LEFT OUTER JOIN MST_TKT_STA_STOCK AS B  ON  a.Extn_Sta_No = b.Extn_Sta_No   
                                        AND B.Oper_DT = '20090713' --둘다 ON 절에 위치함.
                                        AND A.Transp_Oper_Org_CD = '1'
cs

 

4. 잘못된 예  

1
2
3
4
5
 SELECT * --(176개 행 적용됨)
 FROM TBHZM200 AS A 
 LEFT OUTER JOIN MST_TKT_STA_STOCK AS B ON a.Extn_Sta_No = b.Extn_Sta_No   
 WHERE B.Oper_DT = '20090713'    --둘다 where절에 위치
   AND A.Transp_Oper_Org_CD = '1'
cs

결과

1
2
3
4
갯수 503 SELECT count(*FROM TBHZM200 AS A 
갯수 184 SELECT count(*FROM TBHZM200 AS A WHERE A.Transp_Oper_Org_CD = '1' 
갯수 13838 SELECT count(*FROM MST_TKT_STA_STOCK AS B 
갯수 178 SELECT count(*FROM MST_TKT_STA_STOCK AS B WHERE B.Oper_DT = '20090713'
cs




출처 : http://ultteky.egloos.com/10411192


'SQL > MS-SQL' 카테고리의 다른 글

SELF JOIN  (0) 2017.09.19
join Diagram  (0) 2017.09.19
NULL 비교하기  (0) 2017.09.19
일반집계함수 WINDOW FUNCTION  (0) 2017.09.07
순위관련 WINDOW FUNCTION  (0) 2017.09.07

NULL

1
2
3
SELECT * FROM MyTable WHERE MyColumn != NULL
SELECT * FROM MyTable WHERE MyColumn <> NULL
SELECT * FROM MyTable WHERE MyColumn IS NOT NULL
cs


결론부터 말하자면, NULL은 NULL과 같지 않다


NULL은 값이 아니다.

그러므로 다른 값과 비교조차 할 수 없다.

따라서 논리 연산자를 사용하여 값을 비교할 수 없다.


SQL에서는 IS NULL과 IS NOT NULL을 명시하여 NULL을 다룰수 있다.

ISNULL과 =NULL 비교

X IS NULL은 X가 NULL인지 아닌지 판단하는것이고

X = NULL은 X가 NULL과 같은지 판단하는 것이다. X = NULL은 절대 참이 될 수 없다.

'SQL > MS-SQL' 카테고리의 다른 글

join Diagram  (0) 2017.09.19
LEFT OUTER JOIN / WHERE  (0) 2017.09.19
일반집계함수 WINDOW FUNCTION  (0) 2017.09.07
순위관련 WINDOW FUNCTION  (0) 2017.09.07
트리거(Trigger)  (0) 2017.09.06

일반 집계 함수

일반 집계함수에도 OVER(), PARTITION BY를 사용할수있다!

하지만 SQL SERVER의 경우 ORDER BY를 지원하지 않는다

그룹별 소계를 구할때 유용하게 사용할수 있을것 같다.

SUM 함수

SUM 함수를 이용해 파티션별 윈도우의 합을 구할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
SQL > SELECT MGR, ENAME, SAL, SUM(SAL) OVER (PARTITION BY MGR) MGR_SUM 
      FROM EMP;
 
       MGR ENAME             SAL    MGR_SUM
---------- ---------- ---------- ----------
      7566 FORD             3000       6000
      7566 SCOTT            3000       6000
      7698 JAMES             950       6550
      7698 ALLEN            1600       6550
      7698 WARD             1250       6550
      7698 TURNER           1500       6550
      7698 MARTIN           1250       6550
      7782 MILLER           1300       1300
      7788 ADAMS            1100       1100
      7839 BLAKE            2850       8275
      7839 JONES            2975       8275
      7839 CLARK            2450       8275
      7902 SMITH             800        800
           KING             5000       5000
 
14 rows selected.
 
 
SQL> SELECT MGR, ENAME, SAL, 
           SUM(SAL) OVER (PARTITION BY MGR ORDER BY SAL RANGE UNBOUNDED PRECEDING) as MGR_SUM 
     FROM EMP;
 
       MGR ENAME             SAL    MGR_SUM
---------- ---------- ---------- ----------
      7566 SCOTT            3000       6000
      7566 FORD             3000       6000
      7698 JAMES             950        950
      7698 WARD             1250       3450
      7698 MARTIN           1250       3450
      7698 TURNER           1500       4950
      7698 ALLEN            1600       6550
      7782 MILLER           1300       1300
      7788 ADAMS            1100       1100
      7839 CLARK            2450       2450
      7839 BLAKE            2850       5300
      7839 JONES            2975       8275
      7902 SMITH             800        800
           KING             5000       5000
 
14 rows selected.
 
(SQL Server의 경우 집계 함수의 경우 OVER 절 내의 ORDER BY 절을 지원하지 않는다.) 
cs

MAX 함수

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
SQL> SELECT MGR, ENAME, SAL, MAX(SAL) OVER (PARTITION BY MGR) as MGR_MAX FROM EMP;
 
       MGR ENAME             SAL    MGR_MAX
---------- ---------- ---------- ----------
      7566 FORD             3000       3000
      7566 SCOTT            3000       3000
      7698 JAMES             950       1600
      7698 ALLEN            1600       1600
      7698 WARD             1250       1600
      7698 TURNER           1500       1600
      7698 MARTIN           1250       1600
      7782 MILLER           1300       1300
      7788 ADAMS            1100       1100
      7839 BLAKE            2850       2975
      7839 JONES            2975       2975
      7839 CLARK            2450       2975
      7902 SMITH             800        800
           KING             5000       5000
 
14 rows selected.
 
SQL> SELECT MGR, ENAME, SAL 
     FROM (SELECT MGR, ENAME, SAL, MAX(SAL) OVER (PARTITION BY MGR) as IV_MAX_SAL FROM EMP) 
     WHERE SAL = IV_MAX_SAL ; 
 
       MGR ENAME             SAL
---------- ---------- ----------
      7566 FORD             3000
      7566 SCOTT            3000
      7698 ALLEN            1600
      7782 MILLER           1300
      7788 ADAMS            1100
      7839 JONES            2975
      7902 SMITH             800
           KING             5000
 
8 rows selected.
 
cs

MIN 함수

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SQL> SELECT MGR, ENAME, HIREDATE, SAL,
            MIN(SAL) OVER(PARTITION BY MGR ORDER BY HIREDATE) as MGR_MIN 
    FROM EMP;
 
       MGR ENAME      HIREDATE         SAL    MGR_MIN
---------- ---------- --------- ---------- ----------
      7566 FORD       03-DEC-81       3000       3000
      7566 SCOTT      09-DEC-82       3000       3000
      7698 ALLEN      20-FEB-81       1600       1600
      7698 WARD       22-FEB-81       1250       1250
      7698 TURNER     08-SEP-81       1500       1250
      7698 MARTIN     28-SEP-81       1250       1250
      7698 JAMES      03-DEC-81        950        950
      7782 MILLER     23-JAN-82       1300       1300
      7788 ADAMS      12-JAN-83       1100       1100
      7839 JONES      02-APR-81       2975       2975
      7839 BLAKE      01-MAY-81       2850       2850
      7839 CLARK      09-JUN-81       2450       2450
      7902 SMITH      17-DEC-80        800        800
           KING       17-NOV-81       5000       5000
 
14 rows selected.
cs

AVG 함수

EMP 테이블에서 같은 매니저를 두고 있는 사원들의 평균 SALARY를 구하는데, 
조건은 같은 매니저 내에서 자기 바로 앞의 사번과 바로 뒤의 사번인 직원만을 대상으로 한다.

SQL Server에서는 Windowing절이 없다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
SQL> SELECT MGR, ENAME, HIREDATE, SAL, 
     ROUND (AVG(SAL) OVER (PARTITION BY MGR ORDER BY HIREDATE ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)) as MGR_AVG 
     FROM EMP; 
 
       MGR ENAME      HIREDATE         SAL    MGR_AVG
---------- ---------- --------- ---------- ----------
      7566 FORD       03-DEC-81       3000       3000
      7566 SCOTT      09-DEC-82       3000       3000
      7698 ALLEN      20-FEB-81       1600       1425
      7698 WARD       22-FEB-81       1250       1450
      7698 TURNER     08-SEP-81       1500       1333
      7698 MARTIN     28-SEP-81       1250       1233
      7698 JAMES      03-DEC-81        950       1100
      7782 MILLER     23-JAN-82       1300       1300
      7788 ADAMS      12-JAN-83       1100       1100
      7839 JONES      02-APR-81       2975       2913
      7839 BLAKE      01-MAY-81       2850       2758
      7839 CLARK      09-JUN-81       2450       2650
      7902 SMITH      17-DEC-80        800        800
           KING       17-NOV-81       5000       5000
 
cs

COUNT 함수

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SQL>  SELECT ENAME, SAL, 
      COUNT(*) OVER (ORDER BY SAL RANGE BETWEEN 50 PRECEDING AND 150 FOLLOWING) as SIM_CNT
      FROM EMP; 
 
ENAME             SAL    SIM_CNT
---------- ---------- ----------
SMITH             800          2
JAMES             950          2
ADAMS            1100          3
WARD             1250          3
MARTIN           1250          3
MILLER           1300          3
TURNER           1500          2
ALLEN            1600          1
CLARK            2450          1
BLAKE            2850          4
JONES            2975          3
SCOTT            3000          3
FORD             3000          3
KING             5000          1
 
14 rows selected.
cs


참고(COUNT)

COUNT(*)는 그룹지은 행의 총 개수를 리턴한다. 이는 NULL값과 같은 값도 포함한다.

COUNT(ALL expression) 는 그룹지은 행의 총개수를 리턴하는데 NULL값은 제외한 행의 개수를 리턴한다.

COUNT(DISTINCT expression)는 그룹지은 행의 총개수를 리턴하느데 NULL값과 같은 값을 가진 행을 제외한 행의 개수를 센다.


출처 : http://wiki.gurubee.net/pages/viewpage.action?pageId=26744104

         https://docs.microsoft.com/en-us/sql/t-sql/functions/count-transact-sql

'SQL > MS-SQL' 카테고리의 다른 글

LEFT OUTER JOIN / WHERE  (0) 2017.09.19
NULL 비교하기  (0) 2017.09.19
순위관련 WINDOW FUNCTION  (0) 2017.09.07
트리거(Trigger)  (0) 2017.09.06
커서(Cursor)  (0) 2017.09.06

+ Recent posts