출처:  http://jhbench.tistory.com/29

1. Ranking Family

(1) RANK() -  상위 순으로 등수를 부여하는 경우 정렬 결과를 기준으로 전체 순위를 출력

☞사용법

                                                                                                                                      

RANK() OVER(

[PRTITION BY < value expression1>] [,...]

ODER BY<value expression2> [collate clause] [ASC:DESC]

[NULLS FIRST:NULLS LAST])

                                                                                                                                         

OVER : 순위를 부여하기 위한 대상 집합의 정렬 기준과 분할 기준 정의

PARTITION BY : value expression1을 기준으로 분할, 생랼하면 전체 집합을 대상으로 순위부여

ODER BY : 각 분할내에서 데이터를 정렬하는 기준 칼럼 지정

NULLS FIRST|NULLS LAST : 정렬 결과에서 NULL값의 위치 지정

 
(2) DENSE_RANK() - RNAK함수의 변형 동일 순위를 무시한 연속 순위를 출력
  RNAK함수는 1등이 2건인 경우 다음순위를 3등으로 부여 하지만, DENSE_RANK 함수는 다음순위를 2등으로 부여한다. 

질의

 SELECT  id,score,
rank()over(ORDER  BY  score  ASC)as rank,
dense_rank() over(order by score asc)as dense_rank
From ksdb_score;

결과
ID             SCORE       RANK DENSE_RANK
--------- ---------- ---------- ----------
200040394         83          1          1
200020182         88          2          2
200231047         89          3          3
200020182         90          4          4
200020183         90          4          4
200020183         92          6          5
200172058         93          7          6
200040394         95          8          7


(3) CUME_DIST()- 그룹 값 내에서 어떤 값의 cumulative distribution(누적분포)을 계산

☞사용법
                                                                                                                                        

CUME_DIST(expr) 
                                                                                                                                      

 
(4) PERCENT_RANK()-


(5) NTILE() - 출력결과를 사용자가 지정한 그룹 수로 나누어 출력

 ☞사용법

                                                                                                                                        

NITLE(expr) OVER(

[PARTITION BY< value expression1>][,...]

ORDER BY <value espression2> [collate clause] [ASC : DESC]

[NULLS FIRST:NULLS LAST])

                                                                                                                                       

 

질의

 SELECT  Cid,bday,
NTILE(3) OVER(ORDER BY bday) class
FROM ksdb_customer_info;

결과

CID    BDAY          CLASS
------ -------- ----------
100004 60/05/02          1
100010 72/08/02          1
100011 74/09/21          1
100006 75/04/05          1
100001 75/07/01          2
100002 77/02/01          2
100007 80/01/04          2
100003 80/01/25          2

100009 81/01/30          3
100005 82/06/01          3
100008 85/04/04          3

11 개의 행이 선택되었습니다. 

(6) ROW_NUMBER() - 분할별로 정렬된 결과에 대해 순위를 부여하는 기능 분할은 전체 행을 특정 칼럼을 기준으로 분리하는 기능으로 GROUP BY 절에서 그룹화하는 방법과 같은 개념

☞사용법

                                                                                                                                      

 ROW_NUMBER() OVER(

[PARTITION BY< value expression1>][,...]

ORDER BY <value espression2> [collate clause] [ASC : DESC]

[NULLS FIRST:NULLS LAST])

                                                                                                                                        

질의

 SELECT  id,score,
RANK()OVER(ORDER  BY  score  ASC)as rank,
DENSE_RANK()OVER(order by score asc)as dense_rank,
ROW_NUMBER()OVER(order by score asc)as row_number
From ksdb_score;

결과
ID             SCORE       RANK DENSE_RANK ROW_NUMBER
--------- ---------- ---------- ---------- ----------
200040394         83          1          1          1
200020182         88          2          2          2
200231047         89          3          3          3
200020182         90          4          4          4
200020183         90          4          4          5
200020183         92          6          5          6
200172058         93          7          6          7
200040394         95          8          7          8

8 개의 행이 선택되었습니다. 

↑RANK나 DENSE_RANK에서는 점수가 같으면 순위가 같게4,4 나오지만  ROW_NUMBER에서는 순서대로 4,5 로 번호를 부여한다.

2. Aggregate Family  

(1) SUM(), AVG(), MAX(), MIN()  

☞사용법

                                                                                                                                        

AVG([DISTINCT|ALL] expr)

SUM([DISTINCT|ALL] expr) 
                                                                                                                                       

expr의 데이터 타입은 NUMBER 데이터 타입만 가능

 (2) COUNT() - 테이블에서 조건을 만족하는 행의 개수를 반환

     COUNT(*)는 NULL을 가진 행과 중복되는 행을 모두 포함하는 행의 수를 계산

     COUNT(expression)는 NULL을 가진 행을 제외한 행의 수를 계산하여 반환 

(3) STDDEV() VARIANCE() - 인수로 지정된 칼럼에 대해 조건을 만족하는 행을 대상으로 표준편차와 분산을 구하는 함수로 숫자 데이터 타입에만 사용할 수 있으며, NULL 은 계산에서 제외된다. 

(4)RATIO_TO_REPORT()

3. Lead/Lag Family

LEAD() LAG() - 동일한 테이블에 있는 다른 행의 값을 참조하기 위한 함수

LAG 분석함수는 현재 행을 기준으로 이전값을 참조

LEAD 분석함수는 현재 행을 기준으로 이후값을 참조

LEAD LAG 분석함수에서 지정하는 인수는  현재행을 기준으로 몇 번째 행을 참조할 것인지를 지정

음수는 사용할 수 없다.

 ☞사용법

                                                                                                                                        

ROW_NUMBER() OVER(

[PARTITION BY< value expression1>][,...]

ORDER BY <value espression2> [collate clause] [ASC : DESC]

[NULLS FIRST:NULLS LAST])

                                                                                                                                       

 

질의

 SELECT  id,score,
LEAD(score, 1)OVER(ORDER  BY  score)as next_score,
LAG(score,1)OVER(order by score)as prev_score
From ksdb_score;

결과

ID             SCORE NEXT_SCORE PREV_SCORE
--------- ---------- ---------- ----------
200040394         83         88
200020182         88         89         83                 ←88 이후 점수 : 89 
200231047         89         90         88                    88 이전 점수 : 83
200020182         90         90         89
200020183         90         92         90
200020183         92         93         90
200172058         93         95         92
200040394         95                     93

8 개의 행이 선택되었습니다.  

'Oracle' 카테고리의 다른 글

오라클 트리거 트리거란 무엇인가?  (0) 2014.12.02
오라클 기본 문접 ㅎㅎ  (0) 2014.12.02
SYNONYM 오라클 ORACLE  (1) 2014.12.02
오라클 오브젝트 LOB에 대해서  (0) 2014.12.02
탑엔분석? TOP N QUERY 탑엔쿼리  (0) 2014.12.02
블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

SYNONYM 오라클 ORACLE

Oracle 2014. 12. 2. 14:46

- SYNONYM은 오라클 객체(테이블, 뷰, 시퀀스, 프로시저)에 대한 대체이름(Alias)를 말합니다.

 

- Synonym은 실질적으로 그 자체가 Object가 아니라 Object에 대한 직접적인 참조 입니다.

 

- Synonym을 사용하는 이유는...

1) 데이터베이스의 투명성을 제공하기 위해서 사용 한다고 생각하면 됩니다.

    Synonym은 다른 유저의 객체를 참조할 때 많이 사용을 합니다.

 

2) 만약에 실무에서 다른 유저의 객체를 참조할 경우가 있을때 Synonym을 생성해서 사용을 하면은 추후에 참조하고 있는 오브젝트가 이름을 바꾸거나 이동할 경우 객체를 사용하는 SQL문을 모두 다시 고치는 것이 아니라 Synonym만 다시 정의하면 되기 때문에 매우 편리 합니다.

 

3) 객체의 긴 이름을 사용하기 편한 짧은 이름으로 해서 SQL코딩을 단순화 시킬 수 있습니다.

 

4) 또한 객체를 참조하는 사용자의 오브젝트를 감출 수 있기 때문에 이에 대한 보안을 유지할 수 있습니다.Synonym을 사용하는 유저는 참조하고 있는 객체에 대한 사용자의 오브젝트의 소유자, 이름, 서버이름을 모르고 Synonym 이름만 알아도 사용할 수 있습니다.

 

                                                                                                                                      

** Synonyms를 사용하는 경우 **

 

오브젝트의 실제 이름과 소유자 그리고 위치를 감춤으로써 database 보안을 개선하는데 사용 됩니다.

- object에의 Public Access를 제공 합니다.

Remote Database의 Table, View, Program Init를 위해 투명성을 제공 합니다.

Database 사용자를 위해 SQL문을 단순화 할 수 있습니다.

 

Synonym에는 두가지 종류가 있습니다.

1) Private Synonym

 - 전용 Synonym은 특정 사용자만 이용할 수 있습니다.

 

2) Public Synonym

 - 공용 Synonym은 고용 사용자 그룹이며 소유하며 그 Database에 있는 모든 사용자가 공유

 

                                                                                                                                      

** Synonym 생성 문법 **

**[ Syntax ]*************************************************

CREATE [PUBLIC] SYNONYM synonym_name

FOR object_name

*************************************************************

 

- Public : 모든 사용자가 접근 가능한 시노님을 생성 합니다.

              Public Synonym의 생성 및 삭제는 DBA만이 할 수 있습니다.

 

                                                                                                                                      

※ scott USER의 emp테이블을 test USER가 사용하는 예제

 

1. 먼저 scott/tiger USER로 접속해서 test USER에게 emp테이블을 조작할 권한을 부여합니다.

 

SQL> GRANT ALL ON emp TO test;

         권한이 부여되었습니다.

 

test user에 대하여 scott의 emp테이블을 조작할 수 있는 권한을 부여 합니다.

권한이 있어야 select하거나 update, insert할 수 있습니다.

 

2. test USER로 접속해 동의어를 생성합니다.

 

SQL> connect test/test

 

SQL> CREATE SYNONYM scott_emp FOR scott.emp;

시노님이 생성되었습니다.

 

scott USER가 소유하고 있는 emp테이블에 대해 scott_emp라는 일반시노님을 생성 했습니다.

scott 사용자의 emp테이블을 test사용자가 scott_emp라는 동의어로 사용 합니다.

 

-- 시노님을 이용한 쿼리

SQL> SELECT empno, ename FROM scott_emp;

 

-- 일반 테이블을 쿼리

SQL> SELECT empno, ename FROM scott.emp;

이 두쿼리의 결과는 같습니다.

 

   EMPNO ENAME
-------- ---------
    7369 SMITH
    7499 ALLEN
    7521 WARD
    7566 JONES
    7654 MARTIN
    7698 BLAKE
          15 개의 행이 선택되었습니다. 

                                                                                                                                      

** 동의어 삭제 **

 

SQL> DROP SYNONYM scott_emp;

시노님이 삭제 되었습니다.

 

SQL> SELECT empno, ename FROM scott_emp;

라인 1에 오류:

ORA - 00942 : 테이블 또는 뷰가 존재하지 않습니다.

 

                                                                                                                                      

 

 

 

  ================================================ 
    * Oracle Community OracleClub.com 
    * http://www.oracleclub.com 
    * http://www.oramaster.net 
    * 운영자 : 김정식 (oramaster _at_ empal.com)
  ================================================
※ 강좌를 다른 홈페이지에 기재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^


'Oracle' 카테고리의 다른 글

오라클 기본 문접 ㅎㅎ  (0) 2014.12.02
RANK DENSE_RANK CUME_DIST PERCENT_RANK NTILE  (0) 2014.12.02
오라클 오브젝트 LOB에 대해서  (0) 2014.12.02
탑엔분석? TOP N QUERY 탑엔쿼리  (0) 2014.12.02
오라클 PL/SQL 후.  (0) 2014.11.14
블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

출처: http://belselios.tistory.com/entry/%EC%98%A4%EB%9D%BC%ED%81%B4PLSQL-%EB%8C%80%EC%9A%A9%EB%9F%89-%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-%ED%83%80%EC%9E%85-CLOB-BLOB


1. LOB

- LOB은 TEXT, 그래픽, 이미지, 비디오, 사운드 등 구조화되지 않은 대형 데이터를 저장하는데 사용한다.
- 일반적으로 테이블에 저장되는 구조화된 데이터들은 크기가 작지만, 멀티미디어 데이터는 크기가 크다.
- 크기가 큰 데이터는 DB에 저장하기 힘들기 때문에 OS상 존재하는 파일을 데이터베이스가 접근하게 된다.
- LONG, LONG RAW 데이터 유형은 예전에 사용던 것이고, 현재는 대부분 LOB 데이터 유형을 사용한다. 
- TO_LOB 함수를 이용하여 LONG 및 LONG RAW 를 LOB 으로 변경할 수 있다.

종류
  - CLOB : 문자 대형 객체 (Character). Oracle Server는 CLOB과 VARCHAR2 사이에 암시적 변환을 수행한다.
 - BLOB : 이진 대형 객체 (Binary). 이미지, 동영상, MP3 등... 
 - NCLOB : 내셔널 문자 대형 객체 (National). 오라클에서 정의되는 National Character Set을 따르는 문자
 - BFILE : OS에 저장되는 이진 파일의 이름과 위치를 저장. 읽기 전용 모드로만 액세스 가능.

데이터베이스 내부, 외부에 따라

   - 내부 : BLOB, CLOB, NCLOB - Table에 LOB 형식의 컬럼을 생성하고 이곳에 데이터의 실제위치를 가리키는 Locator(위치자) 저장.
  - 외부 : BFILE

특징
- 하나의 테이블에 여러 개의 LOB 열(column) 가능
- 최고 4GB까지 저장
- SELECT로 위치자 반환
- 순서대로 또는 순서없이 데이터 저장
- 임의적 데이터 액세스

LOB 구성
- LOB 값 : 저장될 실제 객체를 구성하는 데이터
- LOB 위치자 : 데이터베이스에 저장된 LOB값의 위치에 대한 포인터
- LOB열에는 데이터가 없고 LOB 위치자만 들어있다.

2. 내부 LOB

- LOB값은 데이터베이스에 저장된다.
- 사용자 정의 유형 속성, 테이블의 열, 바인드 변수, 호스트 변수, PL/SQL변수, 파라미터 또는 결과
- 동시성 방식, 리두 로그 및 복구 방식, 커밋 또는 롤백 트랜잭션 사용 가능
- BLOB 데이터 유형은 Oracle Server 내에서 비트 스트림으로 해석된다.
- CLOB 데이터 유형은 단일 바이트 문자 스트림으로 해석된다.
- NCLOB 데이터 유형은 데이터베이스 national character set 의 바이트 길이에 따라 멀티바이트 문자 스트림으로 해석된다.

내부 LOB 관리
- LOB 데이터 유형을 포함하는 테이블을 생성한 후 이를 채운다.
- 프로그램에서 LOB 위치자를 선언하고 초기화한다.
- SELECT FOR UPDATE를 사용하여 LOB이 포함된 행을 잠그고 해당 행 값을 LOB 위치자에 넣는다.
- LOB 위치자를 LOB값에 대한 참조로 사용하여 DBMS_LOB 패키지 프로시저, OCI호출, OLE용 오라클 객체, 오라클 선행 컴파일러 또는 JDBC를 통해 LOB을 조작한다.
- SQL을 통해서도 LOB 관리 가능(일부)
- COMMIT을 통해 변경사항 적용.

3. CLOB

lob_test1.sql

CREATE TABLE CAR (
        id      NUMBER(6) PRIMARY KEY NOT NULL,
        name    VARCHAR2(20),
        price   NUMBER(10),
        review  CLOB)
/

 

INSERT INTO CAR VALUES (100, 'SM7', 25000000, '삼성에서 나온 SM7을 타보니 정말 편안했다.')
/
INSERT INTO CAR VALUES (200, 'PORTER', 13000000, '역시 1톤트럭의 대표자!!')
/
INSERT INTO CAR VALUES (300, 'VERNA', 9000000, '싸고 좋은 거 같아용~^^*')
/
INSERT INTO CAR VALUES (400, 'SANTAFE', 33000000, EMPTY_CLOB())
/

- 테이블 생성시 CLOB 타입 컬럼을 선언하고, 데이터 입력.
- 따로 SIZE는 지정하지 않는다.
- EMPTY_CLOB() 함수는 위치자(Locator)를 아무 것도 없는 데이터로 초기화시킨다.

'Oracle' 카테고리의 다른 글

RANK DENSE_RANK CUME_DIST PERCENT_RANK NTILE  (0) 2014.12.02
SYNONYM 오라클 ORACLE  (1) 2014.12.02
탑엔분석? TOP N QUERY 탑엔쿼리  (0) 2014.12.02
오라클 PL/SQL 후.  (0) 2014.11.14
오라클 동의어  (0) 2014.11.13
블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

출처:===

http://www.hanbit.co.kr/network/view.html?bi_id=537


Top N Query는 데이터베이스 상에 있는 자료 중 최상위 몇 개의 자료를 보기 위해 사용하는 자료이다. 예를 들어 학교에서 중간고사를 보았고, 이때 총점이 높은 순서대로 10명의 학생을 보기 위해 사용하는 쿼리가 바로 Top N Query의 예가 되겠다. 


------------------------------------------------------------------------------

중복된 row를 제거하라  - 몸풀기

ID        NUM
---------- ----------
         1          1
         2          2
         3          3
         4          4
         5          1
         6          1

위의 데이터를 가지고 아래의 쿼리를 날리면 이런 결과가 나온다. 

SQL> r
  1  select * from temp t1, temp t2
  2* where t1.rowid > t2.rowid and t1.num = t2.num

        ID        NUM         ID        NUM
---------- ---------- ---------- ----------
         5          1          1          1
         6          1          1          1
         6          1          5          1

SQL>

정확하게 중복된 데이터는 이런쿼리

select * from temp t1
where t1.rowid > (select min(rowid) from temp where t1.num = num)
/


        ID        NUM
---------- ----------
         5          1
         6          1

ㅎㅎ 그럼 삭제해볼까?

 1  delete from temp
  2  where id in
  3  (
  4      select id from temp t1
  5      where t1.rowid >
  6      (
  7            select min(rowid) from temp
  8            where t1.num = num
  9      )
 10* )
 11  /

2 행이 삭제되었습니다.

SQL> select * from temp;

        ID        NUM
---------- ----------
         1          1
         2          2
         3          3
         4          4

SQL>

실전! TOP N Query! 

N 번째 까지 구하기 

자 그러면 TOP N을 구해야 할 대상인 샘플을 보도록 하겠다. 언제나 유명한 우리의 EMP테이블이 대상이 될 것이다.

SQL> SELECT * FROM EMP;

     EMPNO ENAME                JOB                       MGR HIREDATE        SAL       COMM     DEPTNO
---------- -------------------- ------------------ ---------- -------- ---------- ---------- -------
      7369 SMITH                CLERK                    7902 80/12/17        800                    20
      7499 ALLEN                SALESMAN                 7698 81/02/20       1600        300         30
      7521 WARD                 SALESMAN                 7698 81/02/22       1250        500         30
      7566 JONES                MANAGER                  7839 81/04/02       2975                    20
      7654 MARTIN               SALESMAN                 7698 81/09/28       1250       1400         30
      7698 BLAKE                MANAGER                  7839 81/05/01       2850                    30
      7782 CLARK                MANAGER                  7839 81/06/09       2450                    10
      7788 SCOTT                ANALYST                  7566 87/04/19       3000                    20
      7839 KING                 PRESIDENT                     81/11/17       5000                    10
      7844 TURNER               SALESMAN                 7698 81/09/08       1500          0         30
      7876 ADAMS                CLERK                    7788 87/05/23       1100                    20
      7900 JAMES                CLERK                    7698 81/12/03        950                    30
      7902 FORD                 ANALYST                  7566 81/12/03       3000                    20
      7934 MILLER               CLERK                    7782 82/01/23       1300                    10

14 개의 행이 선택되었습니다.

SQL>

멋지다! 자 이제 문제는 SAL이 가장 높은 순으로 10명을 뽑으라는 것이다. 일단 간단히 ORDER BY로 SAL을 정렬하면 될 것이다.

SQL> SELECT * FROM EMP
  2  ORDER BY SAL DESC;

     EMPNO ENAME                JOB                       MGR HIREDATE        SAL       COMM     DEPTNO
---------- -------------------- ------------------ ---------- -------- ---------- ---------- -------
      7839 KING                 PRESIDENT                     81/11/17       5000                    10
      7788 SCOTT                ANALYST                  7566 87/04/19       3000                    20
      7902 FORD                 ANALYST                  7566 81/12/03       3000                    20
      7566 JONES                MANAGER                  7839 81/04/02       2975                    20
      7698 BLAKE                MANAGER                  7839 81/05/01       2850                    30
      7782 CLARK                MANAGER                  7839 81/06/09       2450                    10
      7499 ALLEN                SALESMAN                 7698 81/02/20       1600        300         30
      7844 TURNER               SALESMAN                 7698 81/09/08       1500          0         30
      7934 MILLER               CLERK                    7782 82/01/23       1300                    10
      7521 WARD                 SALESMAN                 7698 81/02/22       1250        500         30
      7654 MARTIN               SALESMAN                 7698 81/09/28       1250       1400         30
      7876 ADAMS                CLERK                    7788 87/05/23       1100                    20
      7900 JAMES                CLERK                    7698 81/12/03        950                    30
      7369 SMITH                CLERK                    7902 80/12/17        800                    20

14 개의 행이 선택되었습니다.

SQL>

자 이 쿼리를 한 번 더 둘러싸주면 간단히 10명을 뽑을 수 있다.

SQL> R
  1  SELECT E.* FROM
  2  (
  3      SELECT * FROM EMP
  4      ORDER BY SAL DESC
  5  ) E
  6* WHERE ROWNUM <= 10

     EMPNO ENAME                JOB                       MGR HIREDATE        SAL       COMM     DEPTNO
---------- -------------------- ------------------ ---------- -------- ---------- ---------- -------
      7839 KING                 PRESIDENT                     81/11/17       5000                    10
      7788 SCOTT                ANALYST                  7566 87/04/19       3000                    20
      7902 FORD                 ANALYST                  7566 81/12/03       3000                    20
      7566 JONES                MANAGER                  7839 81/04/02       2975                    20
      7698 BLAKE                MANAGER                  7839 81/05/01       2850                    30
      7782 CLARK                MANAGER                  7839 81/06/09       2450                    10
      7499 ALLEN                SALESMAN                 7698 81/02/20       1600        300         30
      7844 TURNER               SALESMAN                 7698 81/09/08       1500          0         30
      7934 MILLER               CLERK                    7782 82/01/23       1300                    10
      7521 WARD                 SALESMAN                 7698 81/02/22       1250        500         30

10 개의 행이 선택되었습니다.

SQL>

쿼리가 약간 이상해보이는가? E.* 부분이 그럴지도 모르겠다. 저러한 표현이 가능하다는 것 정도는 알아두자. 고백할 것이 있다. 이 쿼리는 오라클 8i 이상에서만 작동하며 오라클 7이나 오라클 8에서는 동작하지 않는다. 왜냐하면 이들 오라클 7이나 8버전에서는 서브쿼리내에 order by를 사용할 수 없기 때문이다. 이러한 경우에는 약간의 편법을 사용해야 한다.

SQL> GET B
  1  SELECT EMPNO, ENAME, ABS(SAL) FROM
  2  (
  3      SELECT E.EMPNO, -E.SAL SAL, MAX(E.ENAME) ENAME FROM EMP E
  4      GROUP BY -E.SAL, E.EMPNO
  5  )
  6* WHERE ROWNUM <= 10
SQL> /

     EMPNO ENAME                  ABS(SAL)
---------- -------------------- ----------
      7839 KING                       5000
      7788 SCOTT                      3000
      7902 FORD                       3000
      7566 JONES                      2975
      7698 BLAKE                      2850
      7782 CLARK                      2450
      7499 ALLEN                      1600
      7844 TURNER                     1500
      7934 MILLER                     1300
      7521 WARD                       1250

10 개의 행이 선택되었습니다.

SQL>

이번엔 쿼리가 약간 복잡하다. 세세히 뜯어보도록 하자.

3      SELECT E.EMPNO, -E.SAL SAL, MAX(E.ENAME) ENAME FROM EMP E
4      GROUP BY -E.SAL, E.EMPNO

group by를 사용해 e.sal으로 묶어준다. 그러나 이렇게만 묶어버리면 sal이 중복되는 row들이 사라져버린다. 따라서 여기서는 EMPNO(EMP테이블의 primary key이다)까지 묶어서 group by를 해주었다. group by 는 desc구문이 존재하지 않으므로 sal이 큰 순으로 나오려면 -E.SAL 형태로 group by를 해주어야 한다. 그리고 group by에 나타나지 않은 컬럼들인 E.ENAME과 은 단순히 MAX()함수를 취해주었다. 이것은 항상 그룹이 단일 row단위로 들어오므로 언제나 단순히 E.ENAME을 돌려준다.

1  SELECT EMPNO, ENAME, ABS(SAL) FROM
2  (
3      SELECT E.EMPNO, -E.SAL SAL, MAX(E.ENAME) ENAME FROM EMP E
4      GROUP BY -E.SAL, E.EMPNO
5  )
6* WHERE ROWNUM <= 10

이제 전체적인 데이터가 도달한 상태에서 10개의 row를 뽑아주기만 하면 된다. 단, SAL 값은 -에 의해 음수로 변해서 왔으므로 이는 다시 ABS함수를 쓰던가 다시 -를 해주어 원래 양수값으로 바꿔줘야 한다. 여기서 제시한 오라클 7,8에서의 서브쿼리에서의 소팅 방법은 group by를 사용해 서브쿼리에서 소트를 할 수 있다는 것과, 소트할 컬럼을 group by의 제일 앞에 명시하고, 다음에 중복된 row가 사라지는 것을 막기위해 pk를 group by에 명시하며 마지막으로, group by 에 명시되지 않았으면서 select 절에 나타난 컬럼들에 max()를 취해준다는 것이다. 그러나 다음과 같이 해볼 수도 있겠다.

SQL> get b
  1  SELECT EMPNO, ENAME, ABS(SAL) FROM
  2  (
  3      SELECT E.EMPNO, -E.SAL SAL, E.ENAME ENAME FROM EMP E
  4      GROUP BY -E.SAL, E.EMPNO, E.ENAME
  5  )
  6* WHERE ROWNUM <= 10
SQL> /

     EMPNO ENAME                  ABS(SAL)
---------- -------------------- ----------
      7839 KING                       5000
      7788 SCOTT                      3000
      7902 FORD                       3000
      7566 JONES                      2975
      7698 BLAKE                      2850
      7782 CLARK                      2450
      7499 ALLEN                      1600
      7844 TURNER                     1500
      7934 MILLER                     1300
      7521 WARD                       1250

10 개의 행이 선택되었습니다.

SQL>

여기서는 모든 컬럼을 group by에 명시하되 sal컬럼만 앞에 가게 해준다는 것이다. 어느 방법이든 맘에 드는 것을 골라 쓰면 되겠다. 

N번째까지가 아니라 N등까지를 구하라 

앞에서의 TOP N 구하는 방식은 SAL순서대로 소팅한 뒤에 제일 먼저 나오는 10개의 row를 뽑은 것이다. 이번에는 N등까지를 구해보도록 하자. 자, 일단 독자 스스로 구현해보도록 하자. 못하면 못하는 대로 한시간은 고민하기 바란다.

  1  SELECT EMPNO, ENAME, SAL FROM EMP E1
  2  WHERE (
  3            SELECT COUNT(1) FROM EMP E2
  4            WHERE E1.SAL < E2.SAL
  5        ) <= 10
  6* ORDER BY SAL DESC
SQL> /

     EMPNO ENAME                       SAL
---------- -------------------- ----------
      7839 KING                       5000
      7788 SCOTT                      3000
      7902 FORD                       3000
      7566 JONES                      2975
      7698 BLAKE                      2850
      7782 CLARK                      2450
      7499 ALLEN                      1600
      7844 TURNER                     1500
      7934 MILLER                     1300
      7521 WARD                       1250
      7654 MARTIN                     1250

11 개의 행이 선택되었습니다.

SQL>

ORDER BY SAL DESC가 존재하지만 이 ORDER BY 문장은 10개의 데이터에 대해서만 SORT를 하므로 SORT비용이 매우 낮음에 주목하라. 그러나 이에 비해 앞서 했던 10번째까지의 사람 구하기는 GROUP BY나 ORDER BY에 의해서 사용되었으므로 SORT비용이 매우 컸다. 

부서별 N등까지를 구하라 

EMP테이블과 자주 같이 사용되는 테이블은 DEPT테이블로서 EMP에 나타난 DEPTNO와 조인하면 부서명을 얻어올 수 있다.

SQL> SELECT EMPNO, ENAME, SAL, DNAME
  2  FROM EMP E, DEPT D
  3  WHERE E.DEPTNO = D.DEPTNO
  4  /

     EMPNO ENAME                       SAL DNAME
---------- -------------------- ---------- ----------------------------
      7369 SMITH                       800 RESEARCH
      7499 ALLEN                      1600 SALES
      7521 WARD                       1250 SALES
      7566 JONES                      2975 RESEARCH
      7654 MARTIN                     1250 SALES
      7698 BLAKE                      2850 SALES
      7782 CLARK                      2450 ACCOUNTING
      7788 SCOTT                      3000 RESEARCH
      7839 KING                       5000 ACCOUNTING
      7844 TURNER                     1500 SALES
      7876 ADAMS                      1100 RESEARCH
      7900 JAMES                       950 SALES
      7902 FORD                       3000 RESEARCH
      7934 MILLER                     1300 ACCOUNTING

14 개의 행이 선택되었습니다.

SQL>

우리가 하고자 하는 것은 각 부서별로 2등까지(두 번째 까지가 아니다)의 사람을 구하는 것이다. 원하는 데이터 형태는 아래와 같이 나타난다.

DNAME        RANK       EMPNO    ENAME
부서A         1         XXXX     홍길동
              2         YYYY     김길동
부서B         1         NNNN     박길동   <- 부서 B에는 한명의 사원만 존재하는 경우
부서C         1         XXXX     서길동
              2         ZZZZ     황길동

이것은 쉽지 않을 것이다. 머리 싸매고 연구해보자.

  1  SELECT * FROM
  2  (
  3      SELECT DNAME, EMPNO, ENAME, SAL, RANK() OVER ( PARTITION BY E.DEPTNO ORDER BY SAL DESC ) RNK
  4      FROM DEPT D, EMP E
  5      WHERE D.DEPTNO = E.DEPTNO
  6  )
  7* WHERE RNK <= 2
SQL> /

DNAME                             EMPNO ENAME                       SAL        RNK
---------------------------- ---------- -------------------- ---------- ----------
ACCOUNTING                         7839 KING                       5000          1
                                   7782 CLARK                      2450          2
RESEARCH                           7788 SCOTT                      3000          1
                                   7902 FORD                       3000          1
SALES                              7698 BLAKE                      2850          1
                                   7499 ALLEN                      1600          2

6 개의 행이 선택되었습니다.

SQL>

답을 보고 의아하게 생각하는 사람들이 있을지 모르겠다. 그러나 사실 ANSI SQL가지고만 풀기에 이 문제는 난이도가 높다. 위에 등장한 SQL코드에는 8i부터 등장한 analytic function이 사용되었다. 이들을 사용해 이 문제와 같은 매우 복잡한 SQL문장을 단 한번에 한 큐에 날려보낼 수 있으며, 더군다나 이들은 OLAP의 다차원 쿼리에 활용될 수 있는 강력한 무기이다. 

OLAP를 위한 글도 analytic function을 위한 글도 아니므로 간단히만 짚어보도록 하자.

3      SELECT DNAME, EMPNO, ENAME, SAL, RANK() OVER ( PARTITION BY E.DEPTNO ORDER BY SAL DESC ) RNK
4      FROM DEPT D, EMP E
5      WHERE D.DEPTNO = E.DEPTNO

바로 이 부분이 핵심인데 그 중에서도 핵심은 RANK() OVER ( PARTITION BY E.DEPTNO ORDER BY SAL )의 의미를 파악하면 이 쿼리를 완전히 아는 것이다. 먼저 RANK() 함수는 순위를 구하는 함수이며 PARTITION 은 부분을 나누는 구문이다. 그리고 ORDER BY는 각 PARTITION(부분) 내에서의 정렬을 위한 컬럼을 명시하는데 쓰인다. 즉, 위의 코드는 E.DEPTNO 를 기준으로 파티션들을 분할하고 그들 각각을 SAL에 의해서 역순으로 정렬한 순위를 얻어오라는 것이다. 이 코드만 실행하면 아래와 같은 결과를 얻는다.

SQL> GET B
  1  SELECT DNAME, EMPNO, ENAME, SAL, RANK() OVER ( PARTITION BY E.DEPTNO ORDER BY SAL DESC ) RNK
  2  FROM DEPT D, EMP E
  3* WHERE D.DEPTNO = E.DEPTNO
SQL> /

DNAME                             EMPNO ENAME                       SAL        RNK
---------------------------- ---------- -------------------- ---------- ----------
ACCOUNTING                         7839 KING                       5000          1
                                   7782 CLARK                      2450          2
                                   7934 MILLER                     1300          3
RESEARCH                           7788 SCOTT                      3000          1
                                   7902 FORD                       3000          1
                                   7566 JONES                      2975          3
                                   7876 ADAMS                      1100          4
                                   7369 SMITH                       800          5
SALES                              7698 BLAKE                      2850          1
                                   7499 ALLEN                      1600          2
                                   7844 TURNER                     1500          3
                                   7521 WARD                       1250          4
                                   7654 MARTIN                     1250          4
                                   7900 JAMES                       950          6

14 개의 행이 선택되었습니다.

SQL>

보다시피 RANK()가 각 파티션 내의 순위를 구해주고 있다.

  1  SELECT * FROM
  2  (
  3      SELECT DNAME, EMPNO, ENAME, SAL, RANK() OVER ( PARTITION BY E.DEPTNO ORDER BY SAL DESC ) RNK
  4      FROM DEPT D, EMP E
  5      WHERE D.DEPTNO = E.DEPTNO
  6  )
  7* WHERE RNK <= 2

그리고 위에서처럼 SELECT문으로 한번 더 묶고 RNK로 FILTERING을 해주어 원하는 결과를 획득한다. 

실제로 analytic function은 매우 강력한 오라클의 분석 기능이지만, ANSI SQL에 위배되고 또한 RDBMS의 근본적인 관계형 맵핑이라는 기본원칙을 무시한다는 비판도 있는 것은 사실이지만, 이러한 쿼리를 역시 100% 완벽한 관계형 데이터베이스 개념에 입각한 쿼리로 바꾸는 것은 거의 불가능할 뿐만 아니라 anlytic function에 비해서 낮은 성능을 보인다. 

이러한 내용에 대한 논쟁에 관심이 있다면 http://www.oracle.com/의 오라클 매거진이나 오라클 매거진 내의 ask Tom 컬럼을 참고하기 바란다. 

참고자료

  • 오라클 SQL 튜닝 실무사례(대청)
  • expert one on one Oracle(wrox)
  • Oracle Magazine


블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

지인과 술을 마시다 들은 소식

티비에 우엉차를 먹고 다이어트 성공한내용 ~~ 오...싶어..

나도 하고 싶어..서 정리해둠...



우엉은 생으러도 먹는거보단 살작 볶아서 우려 먹으면 흡수율이 좋다는데요..

우엉의 효능은 다이어트 방법으로도효.과가있지만 항암효과,피.부미용,여러가지 성인병예.방에탁월해서

건강한사람들도 꾸준히드시면좋은효과기대할수있는약초랍니다.

위에 강조한거 보이시죠? 피부미용.. ㅋ.ㅋ 다이어트~

이렇게 한주전자에 우엉을 넣어 우려드세요.

꾸준히 마시면 이런 몸을 가질수 있겠죠.

'이것저것' 카테고리의 다른 글

컴퓨터 3년만에 업그레이드 하다. dell  (0) 2018.01.11
군함도 송중기  (0) 2017.07.30
안드로이드 롤리팝 5.0 lollipop  (4) 2014.11.18
눈밑떨림증상 영양부족.  (0) 2014.11.11
무료 파일복구 프로그램  (0) 2014.11.07
블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

var selarrrow =  jQuery("#그리드명").jqGrid("getDataIDs"); //그리드의 id값들을 구해옴.

for (var key in selarrrow) //자 순서대로 key 그리드 id값을 넘겨주고

{

var rowdata = jQuery("#그리드명").getRowData(key); //key에 맞는 로우값들을 가져옴.

if(rowdata.TEL==null) //로우에 TEL 항목이 널이 아닌지 체크.

{

continue;

}

rowdata.TEL = rowdata.TEL.replace(/&nbsp;/gi," ");//공백제거 //난 공백제거를 위해서 이거씀.

 jQuery("#그리드명").setCell(key, "TEL", rowdata.TEL); //특정 셀값을 변경하여줌.

}


특정 열이나 행의 데이터 값 특정셀 값을 JQUERY로 변경하고 싶을때. 

'JQUERY' 카테고리의 다른 글

jquery ajax json mvc 스프링 post  (0) 2022.07.20
JUQERY 폰 전화 PHONE 정규식 검사 - 포함  (0) 2014.12.01
jquery정리  (0) 2014.11.20
블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

XXX-XXXX-XXXX형식의 입력을 받았을때

정규식 검사를 하고 싶었다. 

문자를 넣어본건 아니지만.. 숫자와 - 조합일땐 잘 작동했음.. 

    var rgTel = /(\d{2}|\d{3})[-](\d{4}|\d{3})[-]\d{4}$/;


if (!rgTel.test($("#PHONE").val()))

{

         Alert("전화번호 xxx-xxxx-xxxx형식으로 입력해주세요.");

         $("#PHONE").focus();

         return false;

}



'JQUERY' 카테고리의 다른 글

jquery ajax json mvc 스프링 post  (0) 2022.07.20
jqgrid jquery 내부값 변경하기 특정셀값 jqgrid  (0) 2014.12.01
jquery정리  (0) 2014.11.20
블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

$( window ).resize(function() 

    {

   

             if($(window).width()<"890")

                 {$( "#tb" ).width("890px");}

             else

                 { $( "#tb" ).width($( "body").width());}

    });


윈도우 width를 읽어오는 이유는 테이블은 이벤트 발생시 길이가 바로 적용되어 있지 않은 경우가 있음. 

그래서 상위 윈도우의 width 를 읽어옴~ 


'JAVASCRIPT 자바스크립트' 카테고리의 다른 글

table 엑셀 데이타로  (0) 2014.12.24
jqgride formatter  (0) 2014.12.22
자바 스프링 3.x  (0) 2014.11.21
새창에 윈도우 띠우기.  (0) 2014.09.18
javascript에서 trim() 쓰기  (0) 2014.09.18
블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

스프링 동영상 강좌 찾기.

http://www.youtube.com/watch?v=KCs2hXM-2E0


참고~

'JAVASCRIPT 자바스크립트' 카테고리의 다른 글

jqgride formatter  (0) 2014.12.22
jquery table 이나 사이즈 변경시..  (0) 2014.11.28
새창에 윈도우 띠우기.  (0) 2014.09.18
javascript에서 trim() 쓰기  (0) 2014.09.18
날짜 계산 응용  (0) 2014.09.16
블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,

jquery정리

JQUERY 2014. 11. 20. 09:30

페이지 시작시 시작부분.

$(document).ready(function(){   
    블라블라. (필요한 함수들 호출)
 });

jquery는 함수를 연결해서 사용가능.

$("#id명").val().toUpperCase().substring(0,5).toLowerCase();

html페이지내에서 특정 element선택하는방법

태그로 찾기.

$("태그명") -아무것도 안붙임. 

id로 찾기

$(#"id명") - #을 붙임.

class로 찾기. 

#(".클라스명") -클라스명 앞에 .을 붙임.

복수의 element 찾을수 있음

$("태그명,태그명,태그명") - 이런식 id나 class도 될듯. 

필터도 쓸수 있음

$("태그명:first").hide(); -첫번째 태그를 숨긴다.

필터는 차후 정리가 필요할것 같고. 자 다음..

현재페이지의 태그를 탐색하면서 번호를 매김

var i = 1;$("태그명").each(function(){     
    $(this).text(i + ". " + $(this).text()); 
    i++; 
});
-------

$("태그명").each(function(){

    태그명이 동일한것을 순서대로 호출함. 

안에서 사용할땐 $(this)로 접근함. 

}

------------------------------

$("태그명").eq(2).hide(); -검색된 태그의 3번째(0,1,2,3이런식으로 증가) 숨김

$("태그명").slice(2,5).hide(); - 검색된 태그중에서 3~5번째를 감춤.

--------------------------------

next() 함수는 현재 element의 다음 elemen를 접근할수 있음. 

<input type=text class=validate><span></span> 

function validateForm() 

    $(".validate:text").each(function(){ 
    if ($(this).val()==""
        $(this).next().html("이 입력박스를 채우세요"); 
}); 
}


블로그 이미지

은호아빠

여행, 맛집, 일상, 프로그래밍, 개발자, 윈도우, 웹, jsp, spring, db, mysql, oracle, c#

,