출처 - http://egloos.zum.com/wingh/v/4082857

 

Out(외부) Join

 - equijoin 문장들의 한가지 제약점은 그것들이 조인을 생성하려 하는 두 개의 테이블의 두 개
    컬럼에서 공통된 값이 없다면 테이블로부터 테이터를 Return하지 않는 다는 것입니다.

 - 정상적으로 조인 조건을 만족하지 못하는 행들을 보기위해 outer join을 사용합니다.
    Outer join 연산자 "( + )"입니다.

 -조인시킬 값이 없는 조인측에 "( + )"를 위치 시킵니다.


 - Outer join 연산자는 표현식의 한 편에만 올 수 있습니다.


예제1) 일반 조인의 경우

SQL> SELECT DISTINCT(a.deptno), b.deptno
         FROM emp a, dept b
         WHERE  a.deptno = b.deptno

DEPTNO     DEPTNO
---------- ----------
        10         10
        20         20
        30         30


예제2)out join을 했을 경우


SQL>  SELECT DISTINCT(a.deptno), b.deptno
          FROM emp a, dept b
          WHERE  a.deptno(+) = b.deptno

 DEPTNO     DEPTNO
 -------     ----------
     10         10
     20         20
     30         30
                 40

※ 다음의 쿼리를 한번 잘 보시기 바랍니다.

SQL>  SELECT DISTINCT(a.deptno), b.deptno
          FROM emp a, dept b
          WHERE  a.deptno(+) = b.deptno

               ANDa.ename LIKE '%';

    DEPTNO     DEPTNO
---------- ----------
        10         10
        20         20
        30         30

쿼리 결과를 잘 보면 out조인이 되지 않은 것을 알 수 있습니다.
위 쿼리를 out조인이 되기 위해서는 아래와 같이 고쳐야 합니다
.

SQL> SELECT DISTINCT(a.deptno), b.deptno
         FROM emp a, dept b
         WHERE  a.deptno(+) = b.deptno
              AND a.ename(+) LIKE '%'

    DEPTNO     DEPTNO
---------- ----------
        10         10
        20         20
        30         30
                    40

OUT조인 조건이 걸려있는 테이블에는 다른 조건절이 들어와도
똑같이 OUT조인 연산자인 (+)를 해주어야 합니다.  



Oracle9i 부터는 ANSI/ISO SQL표준인 LEFT OUTER JOIN , RIGHT OUTER JOIN, FULL OUTER JOIN를 지원 합니다.


LEFT OUTER JOIN
 왼쪽 테이블에 조인시킬 컬럽의 값이 없는 경우 사용합니다.
 
SQL>SELECT DISTINCT(e.deptno), d.deptno
    FROM dept d LEFT OUTER JOIN emp e
    ON d.deptno = e.deptno;
 
 
RIGHT OUTER JOIN
 - 오른쪽에 테이블에 조인시킬 컬럽의 값이 없는 경우 사용합니다.
 
SQL>SELECT DISTINCT(a.deptno), b.deptno
    FROM emp a RIGHT OUTER JOIN dept b
    ON a.deptno = b.deptno;
 
 
FULL OUTER JOIN
양쪽 테이블에 다 outer join을 거는것을 TWO-WAY OUTER JOIN 또는 FULL OUTER JOIN이라 합니다.
 
SQL>SELECT DISTINCT(a.deptno), b.deptno
    FROM emp a FULL OUTER JOIN dept b
    ON a.deptno = b.deptno;
 
-- 위 세 문장의 결과는 아래와 같습니다.
    DEPTNO     DEPTNO
---------- ----------
        10         10
        20         20
        30         30
                   40
 
LEFT OUTER JOIN과 RIGHT OUTER JOIN의 테이블 순서를 바꾸어 가면서 테스트를 하시면 쉽게 이해를 하실 수 있습니다.

출처 : 오라클 클럽

'IT > DB' 카테고리의 다른 글

[Oracle] pro*c 란 - 초보자를 위한 개념 설명  (10) 2016.05.13
[DB] order by 1의 뜻  (0) 2016.04.25
[DB] oracle NVL함수  (0) 2016.04.25
[Oracle] Grouping(), ROLLUP, CUBE Study 정리  (0) 2016.04.22
-펌-[DB]SQL / MySQL 서브쿼리(SubQuery)  (0) 2016.04.06

1. NVL함수 : 해당 컬럼의 null 값을 다른 값으로 치환해주는 함수
    NVL(value,1) 
     -> value가 null 일경우 1을 반환
                     그렇지 않을경우 value값을 반환

출처 - http://fly32.net/252

 

/****************************************************************
  작성자 : 삼이
  작성일 : 2004-09-30
  제  목 : Grouping(), ROLLUP, CUBE Study 정리
 ****************************************************************/


* ROLLUP 연산자
 - GROUP BY절에 있는 컬럼들을 오른쪽에서 왼쪽의 차례로 그룹들을 생성하고,
   각 그룹에 계산함수를 적용한다.
 - GROUP BY절의 결과는 누적 계산 결과이다.
 

* CUBE 연산자
 - GROUP BY절에 있는 모든 컬럼들에 대한 가능한 모든 조합을 그룹으로 생성한다.
 

* GROUPING 함수
 - 각 결과 행이 CUBE, ROLLUP 연산자들에 의해 계산된 것인지를 알기 위해 사용된다.
 - 해당컬럼에 대해 계산되었다면 0, 그렇지 않다면(컬럼값이 NULL) 1을 반환한다.
 - GROUP BY절에 나타나는 컬럼에 적용된다.


 

사용 예)

  -- table생성(사원이름,급여,부서,직위,입사년도)
  CREATE TABLE roll_test (
    name   VARCHAR2(10),
    sal    NUMBER,
    dept   VARCHAR2(10),
    duty   VARCHAR2(10),
    entYear NUMBER(4)
  );

INSERT INTO roll_Test VALUES('kim' , 1000, 'AA', '00', 2004);
INSERT INTO roll_Test VALUES('no' , 1500, 'AA', '00', 2004);
INSERT INTO roll_Test VALUES('choi', 2000, 'BB', '02', 2003);
INSERT INTO roll_Test VALUES('park', 2000, 'BB', '02', 2003);
INSERT INTO roll_Test VALUES('lee' , 3000, 'CC', '03', 2002);
INSERT INTO roll_Test VALUES('cho' , 4000, 'AA', '04', 2001);
INSERT INTO roll_Test VALUES('lyu' , 4000, 'DD', '04', 2001);
INSERT INTO roll_Test VALUES('ham' , 4000, 'AA', '04', 2001);
INSERT INTO roll_Test VALUES('kang', 7000, 'DD', '05', 2001);
COMMIT;

SELECT * FROM roll_Test;


 

-- 1. 각 부서에 대한 급여 소계를 구하고, 총계를 구하라
--    (하나의 Column Grouping)

-----일반-----------
SELECT dept, SUM(sal)
FROM   roll_Test
GROUP BY dept;
---------------------

----- ROLLUP ---------
SELECT dept, SUM(sal), GROUPING(dept)
FROM   roll_Test
GROUP BY ROLLUP(dept);
-----------------------

----- CUBE ----------
SELECT dept, SUM(sal), GROUPING(dept)
FROM roll_Test
GROUP BY CUBE(dept);
-----------------------

-- 일반적인 GROUP BY를 사용할 경우 급여 소계만 나오고, 총계는 따로 구해야 함
-- ROLLUP과 CUBE 차이점 없음


 

-- 2. 각 부서별, 직위별 급여 소계를 구하고, 총계를 구하라
--    (두개의Column Grouping)

-----NORMAL-----------
SELECT dept, duty, SUM(sal)
FROM   roll_Test
GROUP BY dept, duty;
-----------------------

----- ROLLUP ----------
SELECT dept, duty, SUM(sal), GROUPING(dept), GROUPING(duty)
FROM   roll_Test
GROUP BY ROLLUP(dept, duty);
-----------------------

----- CUBE ----------
SELECT dept, duty, SUM(sal), GROUPING(dept), GROUPING(duty)
FROM   roll_Test
GROUP BY CUBE(dept, duty);
-----------------------

-- ROLLUP은 부서에 대한 소계 / 부서에 대한 직위별 소계만 볼 수 있고,
-- CUBE는 부서에 대한 소계 / 부서에 대한 직위별 소계 / 직위별 소계를 볼 수 있음
-- GROUP BY 내의 왼쪽 컬럼부터 자동으로 오름차순 정렬 됨


-- 3. 각 부서별, 직위별, 입사년도별 급여 소계를 구하고, 총계를 구하라
--    (세개의 Column Grouping)

-----NORMAL-----------
SELECT dept, duty, entYear, SUM(sal)
FROM   roll_Test
GROUP BY dept, duty, entYear;
-----------------------

----- ROLLUP ----------
SELECT dept, duty, entYear, SUM(sal), GROUPING(dept), GROUPING(duty), GROUPING(entYear)
FROM   roll_Test
GROUP BY ROLLUP(dept, duty, entYear);
-----------------------

----- CUBE ----------
SELECT dept, duty, entYear, SUM(sal), GROUPING(dept), GROUPING(duty), GROUPING(entYear)
FROM   roll_Test
GROUP BY CUBE(dept, duty, entYear);
-----------------------


- ROLLUP 사용시 3개의 소계와 1개의 총계를 구할 수 있음
  (부서별, 부서*직위별, 부서*직위*입사년도별, 총계)
  ※ GROUP BY 내의 가장 왼쪽 컬럼을 기준으로 하여 순차적으로 하위 그룹 생성

- CUBE 사용시 7개의 소계와 1개의 총계를 구할 수 있음.
  (부서별, 직위별, 입사년도별, 부서*직위별, 부서*입사년도별, 직위*입사년도별, 부서*직위*입사년도별, 총계)
  ※ 생성 가능한 모든 경우를 그룹 생성
 


사용 예)

* 부서에 대한 소계를 보고 싶을 때
HAVING GROUPING(dept) = 0 AND GROUPING(duty) = 1
AND GROUPING(entYear) = 1;

* 각 부서에 대한 직위별 소계를 보고 싶을 때
HAVING GROUPING(dept) = 0 AND GROUPING(duty) = 0
AND GROUPING(entYear) = 1;

출처 - http://gogorchg.tistory.com/entry/%EC%8B%9C%EC%8A%A4%ED%85%9C-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8

 

 

#define SIGHUP   1
#define SIGINT   2
#define SIGQUIT   3
#define SIGILL   4
#define SIGTRAP   5
#define SIGABRT   6
#define SIGIOT   6
#define SIGBUS   7
#define SIGFPE   8
#define SIGKILL   9
#define SIGUSR1  10
#define SIGSEGV  11
#define SIGUSR2  12
#define SIGPIPE  13
#define SIGALRM  14
#define SIGTERM  15
#define SIGSTKFLT 16
#define SIGCHLD  17
#define SIGCONT  18
#define SIGSTOP  19
#define SIGTSTP  20
#define SIGTTIN  21
#define SIGTTOU  22
#define SIGURG  23
#define SIGXCPU  24
#define SIGXFSZ  25
#define SIGVTALRM 26
#define SIGPROF  27
#define SIGWINCH 28
#define SIGIO  29
#define SIGPOLL  SIGIO
/*
#define SIGLOST  29
*/
#define SIGPWR  30
#define SIGSYS  31
#define SIGUNUSED 31

/* These should not be considered constants from userland.  */
#define SIGRTMIN 32
#define SIGRTMAX _NSIG

 

* 주요 시그널 종류

 

SIGABRT : abort함수를 호출하면 보내지며, 이 시그널을 받으면 코어 덤프하고 종료한다.

 

SIGALRM: alarm 함수를 호출하면 보내지며, 이 시그널을 받으면 종료한다.

 

SIGBUS: 하드웨어 결함이 탐지되면 보내지며, 이 시그널을 받으면 종료한다.

 

SIGCHLD : 자식 프로세스가 종료되면 부모 프로세스에 보내지며 ,wait에서 이 시그널에 의해 깨어난다.

 

SIGCONT:중단되어 있는 프로세스가 이 시그널을 받으면 실행을 하고 실행중인 프로세스가 받으면 무시한다.

 

SIGFPE:0으로 나누기,부동소수점 오류등이 발생했을때 보내지며, 이 시그널을 받으면 코어 덤프하고 종료

 

SIGHUP:터미널 연결이 끊어 졌을때 이 터미널과 연결된 세션 리더 또는 세션에 속한 모든 프로세스들에게 보내지며, 이시그널을 받으면 종료한다.

 

SIGILL:불법 명령어를 실행할때 보내지며, 이 시그널을 받으면 코어 덤프하고 종료한다.

 

SIGINT:터미널에서 인터럽트 키(일반적으로 <CTRL+C>)를 눌렀을때 보내지며, 이 시그널을 받을시 종료

 

SIGKILL:프로세스를 종료 시키기 위해 보내지며,이 시그널을 받으면 반드시 종료한다.

 

SIGPIPE:터미널에서 종료키(일반적으로<CTRL+\>)를 눌렀을때 보내지며, 이 시그널을 받으면 코어 덤프하고 종료

 

SIGSEGV:잘못된 메모리 주소를 접근하고자 할때 보내지며, 이 시그널을 받으면 코어 덤프하고 종료한다.

 

SIGSTOP:프로세스를 멈추기 위해 보내지며, 이 시그널을 받으면 반드시 멈춘다.

 

SIGSYS:잘못된 시스템 호출을 했을 때 보내지며, 이 시그널을 받으면 코어 덤프하고 종료한다.

 

SIGTERM:프로세스를 종료시키기 전에 하던 일을 정리하고 종료할 것을 알릴때 보내진다.

 

SIGTSTP:터미널에서 일시 중지 키(일반적으로(CTRL+Z))를 눌렀을때 보내지며, 이 시그널을 받을시 멈춤

 

SIGTTIN:백그라운드 작업중인 프로세스가 표준 입력을 하려 할때 현재 실행중인 프로세스에 보내지며 이시그널을 받으면 멈춘다.

 

SIGTTOU:백그라운드 작업중인 프로세스가 표준 출력을 하려 할때 현재 실행중인 프로세스에 보내지며, 이 시그널을 받으면 멈춘다.

 

SIGQUIT : 대화형 종료 : 코어 덤프 ( 보통 Ctrl + I)

 

SIGURS1&SIGURS2:사용자가 정의해서 사용할 수 있는 시그널로, 이 시그널을 받으면 종료한다.

 

 

* 시그널을 사용하는데 자주 쓰이는 함수들 : 시그널 마스크와 시그널 세트 다루기

 

int sigemptyset(sigset_t *set) //빈 시그널 집합을 생성

 

int sigfillset(sigset_t *set)//모든 시그널을 포함한 집합을 생성

 

int sigaddset(sigset_t,*set,int signum)//시그널 집합에 추가

 

int sigdelset(sigset_t,*set,int signum)//시그널 집합에서 삭제

 

int sigismember(const sigset_t *set, int signum)//시그널 집합에 signum이 속하는지 확인

 

set: 시그널 집합

 

signum: 시그널 번호

 

 

시그널 처리....

 

void (*signal(int signum,void(*sighandler)(int)))(int)//시그널 처리를 설정한다.

signum:시그널 번호

sighandler:설정할 시그널 핸들러

 

****시그널 핸들러의 종류 3가지*****

함수 이름 : 시그널을 받으면 "함수 이름" 함수가 실행됨.

SIG_IGN  : 시그널을 받으면 무시한다.

SIG_DFL : 시그널을 받으면 시스템에서 기본적으로 설정한 동작을 한다.

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

조금 업글된 기능의 시그널 처리 함수로..

 

int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact)//시그널 처리를 설정

signum:시그널 번호

act : 설정할 행동

oldact:이전 행동

********act의 구조체 분석************

struct sigaction{

void(*sa_handler)(int)//설정할 시그널 핸들러

void (*sa_sigaction)(int,siginfo_t *,void *)//sa_handler 대신 사용될 시그널 핸들러

sigset_t sa_mask;//시그널을 처리하는 동안 블록화할 시그널 집합

int sa_flags;// 시그널 처리 관련 옵션들

void(*sa_restorer)(void);//사용되지 않음

}

 

 

시그널 보내기......

int kill(pid_t pid, int sig)//프로세스에 시그널을 보낸다.

int pause(void)//시그널이 도착할 때까지 실행을 중단시킨다.

int raise(int slg)//자기 자신에게 시그널을 보낸다.

unsigned int alarm(unsigned int seconds)//자신에게 SIGALRM시그널을 보낸다

pid:시그널을 받을 프로세스의 프로세스 ID

sig:보내고자 하는 시그널 번호

seconds: 시그널을 보낼 시간, 초

 

****pid값****

양의정수: 프로세스 ID가 pid인 프로세스에 시그널을 보낸다.

0: kill을 호출한 프로세스가 속한 프로세스 그룹의 모든 프로세스에 시그널을 보낸다

-1:1번 프로세스를 제외한 모든 프로세스에 큰 번호에서 작은 번호의 프로세스 순으로 시그널을 보낸다

-1미만:pid절대값프로세스 그룹의 모든 프로세스에 시그널을 보낸다.

 

 

시그널 블록.....

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset)//블록화될 시그널을 설정한다.

int sigpending(sigset_t *set)//블록화된 시그널을 얻어온다.

int sigsuspend(const sigset_t *mask)//시그널 블록을 설정함과 동시에 시그널이 도착할때까지 중단

how:취할 동작

mask:블록화될 시그널 집합

set: 설정할 시그널 집합

oldset: 이전에 블록화된 시그널 집합

 

****how 값******

SIG_BLOCK : 기존에 블록화된 시그널 집합에 set의 시그널이 추가된다.

SIG_UNBLOCK: 기존에 블록화된 시그널 집합에서 set의 시그널이 제외된다.

SIG_SETMASK:set의 시그널이 블록화된 시그널 집합으로 교체된다.

출처 - http://itguru.tistory.com/66 

 

sprintf

#include <stdio.h> // C++ 에서는 <cstdio>

int sprintf ( char * str, const char * format, ... );



str 에 데이터를 형식에 맞추어 쓴다.
str 가 가리키는 배열에 형식 문자열에 지정한 방식 대로 C 문자열을 쓴다. 쉽게 설명하자면, printf 에서 화면에 출력하는 대신에 화면에 출력할 문자열을 인자로 지정한 문자열에 쓴다는 것이다. 이 때, 인자로 지정한 배열의 크기는 배열에 쓰여질 문자열의 크기 보다 커야만 한다. 주의할 점은 sprintf 함수는 자동적으로 str 맨 마지막에 NULL  문자를 붙이기 때문에 항상 한 칸의 여유가 있어야 한다.

   인자
 

str

C 문자열이 저장될 char 배열을 가리키는 포인터

 
format

위 str 에 쓰여질 문자열을 포함하는 형식 문자열으로, 이는 형식 태그를 포함할 수 있다. 이 때, 형식 태그는 부수적 인자로 지정한 데이터와 치환되어 쓰여지게 된다. 이 때, 데이터가 치환되는 방식은 형식 태그에 의해 좌우된다. 따라서 부수적 인자의 개수는 적어도 형식 문자열에 사용된 형식 태그의 수 보다 많아야 한다.

  • 형식 태그는 아래와 같이 생겼다.

  • %[플래그(flag)][폭(width)][.정밀도][크기(length)]서식 문자(specifier)

  • 이 때 서식 문자(specifier) 는 대응하는 인자를 어떠한 형태로 표현할지를 결정하는데에 가장 중요한 역할을 한다.

  • 서식문자 출력 형태

    c 문자
    a
    d or i 부호 있는 십진법으로 나타난 정수 392
    e 지수 표기법(Scientific notation) 으로 출력하되, e 문자를 이용한다.
    3.9265e+2
    E 지수 표기법(Scientific notation) 으로 출력하되, E 문자를 이용한다. 3.9265E+2
    f 십진법으로 나타낸 부동 소수점 수
    392.65
    g %e 나 %f 보다 간략하게 출력 392.65
    G %E 나 %f 보다 간략하게 출력 392.65
    o 부호 있는 팔진수
    610
    s 문자열
    sample
    u 부호없는 십진법으로 나타낸 정수
    7235
    x 부호없는 16 진법으로 나타낸 정수 (소문자 사용)
    7fa
    X 부호없는 16 진법으로 나타낸 정수 (대문자 사용)
    7FA
    p 포인터 주소
    B800:0000
    n 아무것도 출력하지 않는다. 그 대신, 인자로 부호 있는 int 형을 가리키는 포인터를 전달해야 되는데, 여기에 현재까지 쓰여진 문자 수가 저장된다.
    % % 다음에 %를 또 붙이면 stdout 에 % 를 출력한다.

  • 위 서식 문자를 이용한 다양한 출력 형태는 아래와 같다.

  • #include <stdio.h>
    int main()
    {
        int integer = 123;
        char character = 'c';
        char string[] = "hello, world";
        int* pointer = &integer;
        double pi = 3.141592;
        char buf[100];
        

        sprintf(buf, "integer : (decimal) %d (octal) %o \n", integer, integer);
        printf("%s \n", buf);

        sprintf(buf,"character : %c \n", character);
        printf("%s \n", buf);

        sprintf(buf,"string : %s \n", string);
        printf("%s \n", buf);

        sprintf(buf,"pointer addr : %p \n", pointer);
        printf("%s \n", buf);

        sprintf(buf,"floating point : %e // %f \n", pi, pi);
        printf("%s \n", buf);

        sprintf(buf,"percent symbol : %% \n");
        printf("%s \n", buf);

        return 0;

  • 출력 결과

  • 출처 - http://forum.falinux.com/zbxe/?document_srl=408126&mid=C_LIB&sort_index=readed_count&order_type=desc

     

    설명

    문자열을 문자로 자르는 함수 입니다. 예로, "forum.falinux.com"을 "."으로 자르기를 하면 함수를 호출할 때 마다 "forum", "falinux", "com"의 선두 번지의 포인터를 반환합니다.

    처음에는 자르기 대상인 문자열과 자르기를 위한 문자를 인수로 호출합니다.

    strtok( str, sep);

    이후에는 문자열 대상을 NULL과 자르기를 위한 문자만 인수로 전달합니다.

    strtok( NULL, sep);

    더 이상 구할 문자열이 없다면 NULL이 반환됩니다.

    *** 주의 ***

    strtok()는 잘라 낸 문자열을 구하기 위해 대상 문자열에 NULL을 추가합니다. 즉, 원래의 문자열 내용이 변경 되므로 주의해야 합니다.

    헤더 string.h
    형태 char *strtok(char *restrict s1, const char *restrict s2);
    인수
    char *s1 자르기 대상 문자열
    char *s2 잘라 내기 위한 문자 모임
    반환
    char * 잘라 내기한 문자열의 첫번째 포인터를 반환하며, 문자열이 없다면 NULL을 반환

    예제

    #include <stdio.h>
    #include <string.h>
    
    int main( void)
    {           
       char   str[] = "forum falinux com";
       char	*ptr;
       int	 ndx;
    
       printf( "함수 호출 전: %s\n", str); 
    
       ptr = strtok( str, " ");
       printf( "%s\n", ptr); 
       
       while( ptr = strtok( NULL, " "))
       {
    	   printf( "%s\n", ptr); 
       }
       
       printf( "함수 호출 후: %s\n", str); 
    
       // 함수 호출 후에는 원본 문자열의 내용이 바뀌므로 주의해야 합니다.
            
       printf( "문자열의 변화\n", str); 
      
       for( ndx=0; ndx < 17; ndx++)
    	   printf( "%c %d\n", str[ndx], str[ndx]); 
    	   
       return 0;
    }
    

     

    출처 - http://mintnlatte.tistory.com/444

     

    (1) Declation
    : atoi() : 문자열을 정수로 변환한다.


     int atoi(const char *str)
     
    - str : 변환하기 위한 정수 문자열


    (2) Return Value

    - Succ = 변환에 성공한 정수 값 반환
    - Fail = 0 반환


    (3) Descriptions
    : atoi() 함수는 문자열을 정수로 변환하는 함수이다.

    - 정수로 된 문자열을 전달하여 int 형 정수로 변환한다.
    - 전달된 문자열에 정수가 아닌 문자가 포함될 경우 문자 이전까지만 변환하고 값을 반환한다.
    - 정수가 존재하지 않는 문자열을 전달할 경우 실패하여 0을 반환한다.
    - 음수의 경우 '-'를 음수 부호로 해석해서 정상적인 반환처리가 이루어 진다.
    - 문자열의 앞에 나오는 공백은 탭이나 개행 문자까지 포함해서 모두 무시된다.
    - 부호는 '+'나 '-' 기호 중에서 한 번만 나올 수 있고, 중복되어 나오면 두 번째 기호에서 변환에 실패한다.
    - 공백이나 부호가 "숫자" 중간에 올 경우 공백이나 부호 이전까지만 변환하고 값을 반환한다.
    - int 자료형을 사용하기 때문에, 오버플로우가 발생할 수 있다는 사실을 염두해야한다.
     

    (4) Example

     

    - Source

     

     

     

    - result

     

    출처 - http://forum.falinux.com/zbxe/index.php?document_srl=408173&mid=C_LIB

     

     

    설명

    2개의 메모리 변수에 대해 내용을 비교하여 첫 번째 인수보다 두 번째 인수가 같은지, 큰지, 작은지를 구합니다.

    헤더 string.h
    형태 int memcmp(const void *s1, const void *s2, size_t n);
    인수 void *s1 비교 대상 메모리 포인터
    void *s2 비교할 메모리 포인터
    size_t n 비교할 바이트 크기
    반환 int
    • 양의 정수 : s1 이 s2보다 크다.
    • 0 : s1과 s2가 같다.
    • 음의 정수 : s1보다 s2가 크다.
    예제
    #include <stdio.h>
    #include <string.h>
    
    int main( void)
    {
       char   *ptr1 = "forum";
       char   *ptr2 = "forum";
       char   *ptr3 = "forum.falinux";
       char   *ptr4 = "falinux";
       char   *ptr5 = "com";
    
    
       printf( "%s with %s = %dn", ptr1, ptr2, memcmp( ptr1, ptr2, strlen(ptr1)));
       printf( "%s with %s (ptr1 size)= %dn", ptr1, ptr3, memcmp( ptr1, ptr3, strlen(ptr1)));
       printf( "%s with %s (ptr3 size)= %dn", ptr1, ptr3, memcmp( ptr1, ptr3, strlen(ptr3)));
       printf( "%s with %s = %dn", ptr1, ptr4, memcmp( ptr1, ptr4, strlen(ptr1)));
       printf( "%s with %s (ptr1 size)= %dn", ptr1, ptr5, memcmp( ptr1, ptr5, strlen(ptr1)));
       printf( "%s with %s (ptr5 size)= %dn", ptr1, ptr5, memcmp( ptr1, ptr5, strlen(ptr5)));
    
       return 0;
    }
    

    출처 - http://snowple.tistory.com/360

     

    서브쿼리(Subquery)

    서브쿼리(Subquery)
    란 하나의 SQL 문 안에 포함되어 있는 또 다른 SQL문을 말한다. 서브쿼리는 메인쿼리가 서브쿼리를 포함하는 종속적인 관계이다.


    #메인쿼리
    SELECT * 
    FROM db_table
    WHERE table_fk IN (
    	#서브쿼리
    	SELECT table_fk FROM db_table_other WHERE ..
    	)
    


    조인(Join)은 조인에 참여하는 모든 테이블이 대등한 관계에 있기 때문에 조인에 참여하는 모든 테이블의 칼럼을 어느 위치에서라도 자유롭게 사용할 수 있다. 그러나 서브쿼리는 메인쿼리의 컬럼을 모두 사용할 수 있지만, 메인쿼리는 서브쿼리의 칼럼을 사용할 수 없다.

    조인은 집한간의 곱의 관계이다. 따라서, 1:1 관계 테이블이 조인하면 1(= 1*1) 레벨의 집합이 생성되고, 1:M 관계가 조인하면 M(=1*M) 레벨의 집합이 된다. 그리고 M:N 관계의 테이블이 조인하면 MN 레벨의 집합이 된다.
    그러나, 서브쿼리는 서브쿼리 레벨과는 상관없이 항상 메인쿼리 레벨로 결과 집합이 생성된다. 

    조인쿼리와 서브쿼리 방식을 상황에 맞게 사용하는 것이 중요하다.


    서브쿼리를 사용할 때 주의할 점 

    ① 서브쿼리를 괄호로 감싸서 사용한다.
    ② 서브쿼리는 단일 행 또는 복수 행 비교 연산자와 함께 사용 가능
    ③ 서브쿼리에서는 ORDER BY를 사용하지 못한다.


    서브쿼리가 사용이 가능한 곳 

    - SELECT
    - FROM
    - WHERE
    - HAVING
    - ORDER BY
    - INSERT문의 VALUES
    - UPDATE문의 SET


    서브쿼리의 종류

    ① 단일행 서브쿼리(Single Row Subquery)

    SELECT * 
    FROM Player
    WHERE Team_ID = (
    	SELECT Team_ID 
    	FROM Player
    	WHERE Player_name = "yonglae"
    	)
    ORDER BY Team_name;
    


    ② 다중행 서브쿼리(Multiple Row Subquery)

    SELECT * 
    FROM Team
    WHERE Team_ID IN (
    	SELECT Team_ID 
    	FROM Player
    	WHERE Player_name = "yonglae"
    	)
    ORDER BY Team_name;
    


    ③ 다중컬럼 서브쿼리(Multi Column Subquery)

    SELECT * 
    FROM Player
    WHERE (Team_ID, Height) IN (
    	SELECT Team_ID, MIN(Height) 
    	FROM Player
    	GROUP BY Team_ID
    	)
    ORDER BY Team_ID, Player_name;
    



    위치에 따라 사용되는 서브쿼리

    ① SELECT 절에서 사용되는 서브쿼리

    SELECT Player_name, Height, (
    	SELECT AVG(Height)
    	FROM Player p
    	WHERE p.Team_ID = x.Team_ID) as AVG_Height
    FROM Player x
    


    ② FROM 절에서 사용되는 서브쿼리
    FROM 절에서 사용되는 서브쿼리를 인라인 뷰(Inline View)라고 한다. FROM 절에는 테이블 명이 오도록 되어 있다. 그런데 서브쿼리가 FROM절에 사용되면 뷰(View)처럼 결과가 동적으로 생성된 테이블로 사용할 수 있다. 임시적인 뷰이기 때문에 데이터베이스에 저장되지는 않는다.
    또한, 인라인 뷰로 동적으로 생성된 테이블이여서 인라인 뷰의 칼럼은 자유롭게 참조가 가능하다. 

    SELECT t.Team_name, p.Player_name, p.Height
    FROM Player t, (
    	SELECT Team_ID, Player_name, Back_no
    	FROM Player
    	WHERE Position = 'MF') p
    WHERE p.Team_ID = t.Team_ID;
    


    ③ WHERE 절에서 사용되는 서브쿼리

    SELECT Player_name
    FROM Player 
    WHERE Team_ID IN (
    	SELECT Team_ID
    	FROM Team
    	WHERE Team_country = 'KOR'
    	)
    

    출처 - http://annehouse.tistory.com/45

     

    1. Group by

    SQL> select             avg(saPay), sum(saPay) from sawon; (O)
    SQL> select deptNo, avg(saPay), sum(saPay) from sawon;
    (X)
         20개의 data┘           └각각 1개 data┘
    *
    ORA-00937: 단일 그룹의 그룹 함수가 아닙니다
    => 해결책! GROUP BY
    SQL> select deptNo, avg(saPay), sum(saPay) from sawon group by deptNo;

    + Recent posts