SQL 출처
https://cafe.naver.com/an02
school201712.sql
챕터번호 | key points |
---|---|
1 | OR, IN, REPLACE, TRIM, INNER JOIN |
2 | DECODE, CASE, 다중 CASE문(바보짓), SUBSTR, OUTER JOIN, NULL 허용 컬럼, DUAL, UNION ALL, NVL, NVL2, STRING 형태 숫자들의 정렬 방법, |
3 | 날짜 조건 주는 방법 3가지, JOIN과 UNION, 날짜 BETWEEN 대신 부등호, SELECT문의 특정 컬럼 안보이게 하는 법, SELECT절에서 서브쿼리 vs. FROM절에서 서브쿼리, UNION과 UNION ALL |
4 | 최근 N건의 데이터 뽑는 방법 2가지, RANK |
5 | GROUP BY, GROUP BY 칼럼 피하는 법, CASE에 SUM |
6 | GROUP BY ROLLUP, 총계, 소계, 총계/소계용 테이블 공백처리, CASE 활용 |
7 | 연습문제 (pass) |
8 | function |
9, 9-1 | 집계함수, EXIT-IN |
11 | 부등호 조인 |
12 | IN, GROUP BY-HAVING, PARTITION BY, 중복인 대상 찾는 2가지 방법 |
추가) | PK(논리 PK, 물리 PK), INDEX, TRIGGER, SEQUENCE, DB 설계 시 HISORY 남기기, FUNCTION, PROCEDURE, PACKAGE |
기본 규칙(권장)
WHERE 1 = 1
한 줄씩 주석처리해서 유지보수 작업할 때 쿼리 문법 에러 안나기 때문에.
1=1 해놓고 다음줄 AND 부터 조건들 쓰기
들여쓰는 방법
select (space bar 세 번) 조건
컴마의 위치
한 줄씩 주석처리해서 유지보수 작업할 때 쿼리 문법 에러 안나기 때문에.
컴마를 앞에 위치
테이블의 구조 검색
DESC 테이블명;
현재 스키마의 모든 테이블 목록을 검색
SELECT * FROM TAB;
1번
AND와 OR를 같이 쓰는 것보다 IN 하나만 쓰는 게 더 효율적인 경우가 있다.
EX) 개발 직무의 ID가 2002, 2003인 사람을 구해라
방법 1) OR 쓰기
SELECT ENO
, ENAME
, SEX
, JOB
, HDATE
FROM EMP
WHERE 1 = 1
AND JOB='개발'
AND ENO='2002'
OR ENO='2003';
방법 2) IN 쓰기
SELECT ENO
, ENAME
, SEX
, JOB
, HDATE
FROM EMP
WHERE 1 = 1
AND JOB='개발'
AND ENO IN ('2002' ,'2003');
=> 구해야하는 ID의 갯수가 1000개라면? 방법 1로 구한다면 답 없음.. 100줄 생길 것.
=> IN을 사용해 훨씬 간편하게 관리 OK.
INNER JOIN을 하는 경우는 여러가지가 있다.
- INNER JOIN 테이블명 ON 조건
SELECT *
FROM EMPLOYEES E
INNER JOIN DEPARTMENTS D ON D.DEPARTMENT_ID = E.DEPARTMENT_ID
WHERE 1 = 1
AND SALARY <= 3000
;
-> 어떤 테이블들이 JOIN 되었는지 가독성 떨어짐.
-> JOIN 테이블이 많아지면 더 골치아픔.
AND절에 JOIN 조건 넣는 것 추천
- AND 절에 하는 법
SELECT *
FROM EMPLOYEES E
, DEPARTMENTS D
WHERE 1 = 1
AND E.DEPARTMENT_ID = D.DEPARTMENT_ID
AND SALARY <= 3000
;
INNER JOIN 시 동일 테이블에 2개의 별명을 만들어야 하는 경우
조인할 테이블 a, b가 다음과 있고,
a(벤더 번호, 제조사 번호)
b(벤더 번호, 이름)
일때
a.벤더번호 = b1.벤더번호
a.제조사 번호 = b2. 벤더번호
조회(b1.이름, b2.이름) 이 필요할 때 쓰임
DATE 타입인데 CHAR 타입으로 변환하여 조건을 만족해야 하는 경우
아래와 같이 표현하고 싶을때!
SELECT JOB_ID
, END_DATE
, TO_CHAR(END_DATE,'YYYYMMDD')||JOB_ID AS EXAMPLE
FROM JOB_HISTORY
;
아래 실행하면 2019/01/01MANAGEMENT로 안나오고
20190101MANAGEMENT로 나온다는 점!
OUTER JOIN를 쉽게 이해하는 방법
두 테이블 중 모자라는 테이블 옆에 (+)를 해주자.
OUTER JOIN을 해야하는 경우
: NULL이 허용되는 칼람이 있을 경우, 꼭 OUTER JOIN을 해줘야 함!
OUTER JOIN 즉, (+) 표시를 안해주면 NULL이 있는 칼람들이 지워진 쿼리문이 보여짐
= 몇몇 데이터가 삭제된 결과 테이블이 나온다는 뜻....
날짜 형식을 지키자
TO_CHAR(칼람명, 'YYYY-MM-DD HH:MM:SS') 보다,
TO_CHAR(칼람명, 'YYYY-MM-DD HH24:MM:SS') 가 더 정확!
SELECT ENO
, ENAME
, SEX
, JOB
, TO_CHAR(HDATE, 'YYYY-MM-DD HH24:MM:SS') AS HDATE
FROM EMP;
차이점은 아래와 같음
형식 | 설명 | HOW |
---|---|---|
HH, HH12 | 시간을 01~12시 형태로 | TO_CHAR(SYSDATE, ‘HH’) → 04 |
HH24 | 시간을 01~23시 형태로 | TO_CHAR(SYSDATE, ‘HH24’) → 16 |
REPLACE와 TRIM
별명 부가 시 주의사항
AS를 사용(or 생략)한다는 것은 누구나 다 아는 사실,,,
SELECT ENAME
, SEX
, JOB
, SAL
, SAL*12 + COMM 연봉
FROM EMP;
그러나 별명에 공백이 있거나 숫자가 있다면 이중 인용 부호를 사용하여 별명 부가해야 함
SELECT ENAME
, SEX
, JOB
, SAL
, SAL*12 + COMM "1000연봉"
FROM EMP;
NULL 연산을 위한 NVL 함수의 사용
- NVL 함수
= NULL을 다른 값으로 치환해주는 단일 행 함수
SELECT ENAME
, SAL
, COMM
, SAL*12 + NVL(COMM,1) "연봉"
FROM EMP;
-> COMM(=보너스 금액) 이 NULL이면 1로 치환한다.
연결 연산자 ||
SELECT ENAME||'의 월급은 '||SAL||'이다'
FROM EMP;
2번
//참고 url
case문
http://www.gurubee.net/lecture/1028
- 날짜 조건 주는 방법 3가지
7월 1일 전까지의 데이터를 구하는 쿼리문이라고 가정
방법 1) < end date + 1
방법 2) < end date + 0.99999
방법 3) < (end date+1)
기준 < TO_DATE('20170630', 'YYYYMMDD') + 1
기준 < TO_DATE('2017-06-30','YYYY-MM-DD') + 0.99999
기준 < TO_DATE('20170701', 'YYYYMMDD')
=> 1번 방법이 제일 정확함. 오차가 없는 방법
- 날짜 BETWEEN 대신 부등호
date1 BETWEEN '2017-01-01' AND '2017-06-30' --between 쓴 방법
(date1 >= TO_DATE('20170101','YYYYMMDD') AND date2 < TO_DATE('20170630', 'YYYYMMDD') + 1 --부등호 쓴 방법
-> 부등호 쓰는 게 더 직관적이다!
- SELECT문의 특정 컬럼 안보이게 하는 법
select절에서 a,b,c,d,e,f가 있다고 할 때, a,b만 보여지고 싶다면?
SELECT a,b
FROM (
SELECT a,b,c,d,e,f
FROM CGM_EQUIPMENT CE
WHERE 1=1
)
);
- SELECT절에서 서브쿼리 / FROM절에서 서브쿼리
SELECT절 서브쿼리: RETURN 값이 1개여야 함. (rownum=1로 강제성 부여할 수도 있음 - 근데 함부로 하면 값 다르게 나옴.)
FROM절 서브쿼리: 다 가능. data 여러 건 상관 없음.
참고 링크:
- UNION과 UNION ALL
UNION: 교집합 중복되는 것들은 제거해주고 한 번만 나오게. 정렬도 해줌. 느림.
UNION ALL: 교집합을 이중으로 표시. 테이블에 있는 것 다. 정렬 안해줌. 순서대로 출력
-> 중복되는 게 없으면 union all 쓰는게 더 효율적
union, union all 그림으로 표시: https://uple.net/m/1689?category=19050
4번
DENSE (중복 있으면 그만큼 순위 공백이 생김)
DENSE_RANK (중복 있어도 순위 공백 없음)와
ROW_NUMBER (중복된 순위가 나오지 않음)
- 데이터가 최근인 것 순으로 2건만 출력하는 방법 1) - ROW_NUMBER()
SELECT A
FROM (
SELECT A
, ROW_NUMBER() OVER (ORDER BY A DESC) AS RK
FROM 테이블 MH
WHERE 1 = 1
)
WHERE 1 = 1
AND RK <= 2
;
- 데이터가 최근인 것 순으로 2건만 출력하는 방법 2) - DENSE_RANK()
SELECT A
FROM (
SELECT A
, DENSE_RANK() OVER (ORDER BY A DESC, B DESC) AS RK
FROM 테이블 MH
WHERE 1 = 1
)
WHERE 1 = 1
AND RK <= 2
;
- 데이터가 최근인 것 순으로 2건만 출력하는 방법 3) - RANK()
SELECT A
FROM (
SELECT A
, RANK() OVER (ORDER BY A DESC) AS RK
FROM 테이블 MH
WHERE 1 = 1
)
WHERE 1 = 1
AND RK <= 2
;
5번
- GROUP BY() 안에 칼럼들 다 때려 박는 방식 피하는 법
테이블 EX)
AAA | 123 | SE | D1 |
---|---|---|---|
AAA | 123 | SE | D1 |
AAA | 123 | SE | D9 |
AAA | 123 | SE | D10 |
AAA가 같으면 123도 같고 SE도 같을 수 밖에 없는 구조. D의 사이즈만 달라지는 테이블 구조
이 테이블의 특성 덕분에 MAX(칼럼명)을 쓰는 걸로 발상의 전환해서, GROUP BY에 모든 컬럼을 죄다 때려 박지 않아도 됨
SELECT AAA
, MAX(123) --MAX 집계함수를 썼기에 에러 안 남 + GROUP BY()에 컬럼명 다 안써져도 됨
, MAX(SE)
, COUNT(D9)
FROM 테이블 MC
WHERE 1 = 1
GROUP BY MC.AAA
;
- SUM을 이용해 COUNT하기
, COUNT(DECODE(X, 'R9',1,NULL)) AS X
, SUM(CASE WHEN XX = 'D9' THEN 1 ELSE 0 END) AS XX --CASE에 SUM 쓰는 방법
6번
소계 총계 예시 테이블.
aaa | 123 | 2 |
---|---|---|
aaa | 999 | 3 |
aaa | SUB TOTAL | 5 |
bbb | 123 | 3 |
aaa | SUB TOTAL | 3 |
GRAND TOTAL | 8 |
지금은 내장함수 ROLLUP() 이용하면 되는데,
옛날 같은 경우, 주어진 테이블 A를 FULL JOIN을 함. 3번을 함.
그럼
A
A
A
이렇게 있을텐데, 각각 역할을 다르게 해서 결과물 테이블을 만든거임.
첫번째 A는 원래대로 GROUP BY 해주고, 두 번째 A는 SUB TOTAL 만들어주고, 세 번째 A는 GRAND TOTAL 만들수 있게 해준거지.
//참고 url
총계 소계 표시 방법 http://blog.naver.com/PostView.nhn?blogId=acatholic&logNo=90148766925
하위 레벨 https://thebook.io/006696/part01/ch05/03/01/
GROUPING 칼람 개수별 하위 그룹 https://fly32.net/252
GROUPING_ID 10진수로 리턴 로직 https://m.blog.naver.com/PostView.nhn?blogId=minis24&logNo=80100555203&proxyReferer=http%3A%2F%2Fwww.google.com%2Furl%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D2%26ved%3D2ahUKEwis2uvZ6MLlAhWPc3AKHbR3AeoQFjABegQIAhAB%26url%3Dhttp%253A%252F%252Fm.blog.naver.com%252Fminis24%252F80100555203%26usg%3DAOvVaw3Par0t42UZ01QmTQtRXTqE
그루비 http://www.gurubee.net/lecture/2679 소계 총계 각기 표시
소계 총계 표시 여러 방법 http://blog.naver.com/PostView.nhn?blogId=acatholic&logNo=90148766925
- ROLLUP - 총계/소계 표시할 때 쓰인다~
ROLLUP() 안에 들어가는 테이블 어떤 게 들어가는지 유의하기.
- 총계/소계 표시를 위한 CASE문
https://softarchitecture.tistory.com/63 의 테이블 결과 스샷으로 예시
- 소계를 위해 신경써야 할 것:
조건) JOB이 NULL일 때
- 총계를 써줘야 하는 조건:
조건) DEPTNO가 NULL일 때
총계란의 JOB란도 NULL로 비워줘야 함.
소계/총계를 테이블에 표시 ex)
SELECT
NVL(DEPTNO, '총계') AS DEPTNO
, CASE
WHEN DEPTNO IS NULL AND JOB IS NULL THEN NULL --총계란의 JOB 컬럼 빈칸만들기 위한 case문
WHEN JOB IS NULL THEN '소계' --null이면 소계써주고
ELSE JOB --아니면 원래값 출력
END CNMV_STS_CD
8번
[function 생성 및 이용하는 법] 게시물 확인 ->
9번
//참고 url
EXIST와 NOT EXIST 예시. 둘 다 같게 어떻게? https://runtoyourdream.tistory.com/112
스택오버플로에서 9번 해결 방법 https://stackoverflow.com/questions/20893403/sql-select-query-excluding-certain-values
- IN과 EXISTS
IN: () 안에 있는 특정값이나 서브쿼리의 결과값이 포함이 되는지만 체크
AND (기본키1, 기본키2) NOT IN (SELECT 기본키1, 기본키2 FROM 테이블 WHERE 칼럼1 = '123')
EXISTS: ()안의 서브쿼리로 부터 해당 컬럼의 값이 존재 유무만 체크
FROM 테이블2 LA
~
~
AND NOT EXISTS (
SELECT 기본키1 --이부분은 아무거나 써도됨. 이 서브쿼리문 전체의 유무만 파악하는게 NOT EXISTS이기 때문. 굳이 컬럼값일 필요 X
FROM 테이블 LR
WHERE 1 =1
AND 칼럼1 = '123'
AND LA.기본키1 = LR.기본키1
AND LA.기본키2 = LR.기본키2
)
;
=> 이 2가지 결과는 동일.
그러나, EXISTS가 훨씬 빠름
이유는??
-IN을 이용하게 되면 서브쿼리 전체를 먼저 스캔하고 tableA의 모든 레코드에 대해 IN에서 추출된 데이터와 비교하게 되므로 서브쿼리의 추출되는 레코드가 많다면 성능이 저하됩니다.
-EXISTS와 조인을 이용하는 방법은 비교해서 참 또는 거짓만 리턴하므로 서브쿼리의 추출되는 데이터가 많다면 훨씬 좋은 성능을 보이게 됩니다.
http://ojc.asia/bbs/board.php?bo_table=LecOrccleTun&wr_id=116
12번
//참고 url
PARTITIONI BY 아이디어(중복체크용도) https://hmjkor.tistory.com/9
분석 함수 그루비 http://www.gurubee.net/lecture/2671
- 중복인 대상 찾는 2가지 방법
- group by - having 이용
SELECT 칼럼1
FROM 테이블명
GROUP BY 칼럼1
HAVING COUNT(*)>1
;
중복이 아닌 대상 찾기
SELECT 칼럼1 FROM 테이블명 GROUP BY 칼럼1 HAVING COUNT(*)=1 ;
- row_number() over(partition by ~ order by ~) 이용
SELECT 칼럼1
FROM (
SELECT 칼럼1
, ROW_NUMBER() OVER(PARTITION BY 칼럼1 ORDER BY 칼럼2) CNT
FROM 테이블명
)
WHERE 1 = 1
AND CNT > 1
GROUP BY 칼럼1
;
- group by - having
having 절: gouping된 것에 있어, 집계함수로 조건을 줄 수 있다.
틀린 예 1)
SELECT 칼럼명1 FROM 테이블명
GROUP BY 칼럼명1
HAVING 칼럼명2 = 3;
'ORA-00979: GROUP BY 표현식이 아닙니다.' -> 에러 뜸!
틀린 예 2)
SELECT 칼럼명1 FROM 테이블명
GROUP BY 칼럼명1
HAVING COUNT(칼럼명2);
'ORA-00920: 관계 연산자가 부적합합니다' -> 에러 뜸!
맞는 예)
SELECT 칼럼명1 FROM 테이블명
GROUP BY 칼럼명1
HAVING COUNT(칼럼명2) > 1;
- (칼럼 여러개) IN (칼럼 여러개)
: 이 여러개 컬럼들의 조건들에 맞는 것들을 다 검사
ex)
쌍으로 IN 연산자에 부합해야할 때가 있을 수 있음 - 이때 유용
SELECT *
FROM A
WHERE (A.1, A.2, A.3) IN (
SELECT B.1, B.2, B.3
FROM B
WHERE ....
);
출처: https://derveljunit.tistory.com/174 [IT를 보고, 듣고, 사색하고]
11번
//참고 url
부등호 조인 https://tedock.tistory.com/156
- 누계 계산법 2가지
- 부등호 조인 이용
= 한 테이블을 FROM절에 두 번 가져오기 -> 한 테이블은 SUM용, 한 테이블은 원본용 으로 -> 조인!
SELECT GR.테이블1
, MAX(GR.환율칼럼) 당월_환율
, SUM(GR2.환율칼럼) 누계_환율
FROM 테이블1 GR
, 테이블1 GR2
WHERE 1 = 1
AND GR.기본키 >= GR2.기본키 --부등호 조인
AND GR.기본키2 = GR2.기본키2 --다른 조인 조건
AND GR2.기본키3 = 'USD' --다른 조인 조건
AND GR.기본키3 = GR2.기본키3 --다른 조인 조건
GROUP BY GR.기본키 --부등호 조인한 기본키로 GROUP BY, ORDER BY
ORDER BY GR.기본키 --부등호 조인한 기본키로 GROUP BY, ORDER BY
;
- SUM() OVER (ORDER BY ~) 이용법
SELECT 기본키
, GR.환율칼럼 당월_환율
, SUM(GR.환율칼럼) OVER (ORDER BY GR.기본키) 누계_환율
FROM 테이블1 GR
WHERE 1 = 1
AND GR.기본키3 = 'USD'
;
- 논리 pk, 물리 pk
논리 pk: (프로그램상으로) 중복이 들어올 수 없는 값
물리 pk: 눈에 보이는 pk. ex) sequence들
-보통 논리,물리 pk를 같이 씀
- history를 남길 수 있게 db를 설계하자
: 데이터 삭제의 경우, 실제로 삭제하는 것보다, delete_flg 칼럼을 만드는 것
null값 방지를 위해 default로 delte_flg='n'를 해주고 삭제여부를 이 컬럼에 표시하는 것
ex) (출처: https://12bme.tistory.com/246)
이름 | 역할 | 의미 |
---|---|---|
_FL | FLAG | 플래그값이다. 종종 삭제하지 않은 테이블에서 삭제플래그를 많이 사용한다. 값은 0/1이나 Y/N을 많이 사용한다. |
장점: CUD시 추적관리에 좋다. 그러나 데이터 양이 많이 발생하는 곳에는 x
- sequence를 적극 활용하자
각 칼럽의 개수를 MAX(+1)로 관리한다면?
-> 동시작업시 PK 중복 에러날 수 있음.
Sol) Oracle에서는 (테이블 속성이 아닌) 별도의 sequence 객체를 생성해서 이용할 수 있다.
MySQL 에서는 컬럼에 auto_increment 속성을 지정
출처: https://offbyone.tistory.com/239 [쉬고 싶은 개발자]
insert 작업 시 이 sequence를 무조건 거치기에, 동시성에 있어서 문제 될 일 x
- DB OBJECT의 종류
DB OBJECT | 설명 |
---|---|
테이블 | 데이터를 담고 있는 객체 |
인덱스 | 테이블에 있는 데이터를 빠르게 찾기 위한 객체. > 칼럼들의 순차적인 의미를 부여. (ex. 전화번호부, 사전) |
뷰 | 하나 이상의 테이블을 연결해 마치 테이블인 것처럼 사용하는 객체 |
트리거 | 시점 기준. before/after 2가지로 나눠서 스크립트를 짤 수 있게 도와줌. (ex. CUD라면 6가지) 존재 이유: 중복을 피하기 위해 |
패키지 | 용도에 맞게 함수나 프로시저를 하나로 묶어 놓은 객체. 관리의 포인트를 둠. (ex. 모듈별/성격별로 나눌 수 있음) |
함수 | 특정 연산을 하고 값을 반환하는 객체. return 값이 1개. -> 쿼리에서 사용할 수 있음. |
프로시저 | CUD 성격의 일련의 과정을 복합적으로 가지고 있는 객체. 함수와 비슷하지만 값을 반환하지는 않는 객체. return 값이 여러 개일 수 있다. 장점: 복잡한 흐름을 잘 명시. 빠르다. |
시퀀스 | 일련번호 채번을 할 때 사용되는 객체 |
https://thebook.io/006696/part01/ch02/01/01/
- procedure와 function
프로시져 :
업무를 맡기는 목적 (CRUD 업무 로직)
로직을 기술 하여 해당 업무 처리를 위임시켜 사용 할 수 있도록 하는 용도로 많이 사용됨
프로시저 형식
CREATE OR REPLACE PROCEDURE 프로시저명 ( 파라미터1 데이터타입 [ IN | OUT | INOUT ] , ~)
IS [AS]
변수 선언부..;
BEGIN
프로시저 본문 처리..;
EXCEPTION
예외처리..;
END;
출처: https://arrkaize86.tistory.com/entry/오라클-프로시저PROCEDURE [송군함대]
함수 :
로직을 도와주는 목적
자주 쓰는 로직을 모듈화 시켜 현재 하는 업무를 서포트 해주는 목적으로 많이 사용됨
사실 프로시져나 펑션은 둘다 결과값도 리턴되고 ( 프로시져는 out 파라메터로 ) 하지만
펑션(function)은 조회를 제외한 나머지 데이타 조작은 구현하기 사용하기 힘듭니다.
하지만 프로시져는 강력하게 데이타조작 처리가 가능하기 때문에 데이타를 배치 처리에 많이 사용 됩니다.
소위 말하는 사정업무라고 할까요.
https://okky.kr/article/212226
- 트리거
= 테이블에 대한 이벤트를 자동으로 실행 해 주는 것이다. 즉, 자동으로 실행되는 PL/SQL 문이라고 보면 된다.
예를 들면 A,B,C 라는 테이블에 공통으로 사원번호가 있다 . A테이블의 사원번호가 지워지면 B,C테이블의 회원번호도 자동으로 지워지게하거나 Update , insert 등을 할 수 있다.
-트리거의 종류
1. SQL문의 실행시기에 따른 분류
: before 트리거-SQL 문장이 실행되기 전 트리거가 먼저 실행됨
: after 트리거-SQL 문장이 실행된 다음 트리거가 먼저 실행됨
- SQL문에 의해 영향 받는 각 row에 따른 분류
: row 트리거-SQL 문장의 각 row에 대해 한번 씩 실행
: statemnet 트리거-SQL 문장에 대해 한번만 실행
(DEFAULT TRIGGER)
트리거 형식
CREATE or REPLACE TRIGGER trigger_name
BEFORE or AFTER [INSERT,DELETE,UPDATE] ON table_name
[Referencing OLD AS {변경전 값을 참조하는 변수명} NEW AS {변경후 값을 참조하는 변수명}]
[ FOR EACH ROW ]
DECLARE
-- 변수선언
BEGIN
-- 트리거 코드(PL/SQL 코드)
EXCEPTION
WHEN
--익셉션
END;
트리거 예시
CREATE OR REPLACE TRIGGER trigger_name
BEFORE UPDATE
ON table_name
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
BEGIN
INSERT INTO TABLE_MOD
(aa,bb,cc)
VALUES
(:OLD.aa,:OLD.bb,:OLD.cc);
https://thatisgood.tistory.com/entry/oracle-Trigger오라클-트리거
- 집계함수에는 무조건 1개 이상의 ROW가 발생한다. (데이터가 없어도!)
SELECT MAX(ACCT_XCH_RT_YRMON)
FROM GL_MON_XCH_RT GR
WHERE 1 = 1
AND GR.CURR_CD = '월루'
;
결과: 1 rows
-> 코딩 시 유용하게 사용 가능-무조건 결과값이 있기에. nodatafound 같은 에러 발생 x
-> procedure, function에서도 loop 돌 때 한 줄이라도 결과값 나오게 할 때도 쓰임. nullpointerror 나오기도 하기 때문
- SELECT절은 데이터 없으면 값이 아예 안나옴
SELECT ACCT_XCH_RT_YRMON
FROM GL_MON_XCH_RT GR
WHERE 1 = 1
AND GR.CURR_CD = '월루야호'
;
결과: 0 rows
'DATABASE > ORACLE' 카테고리의 다른 글
[ORACLE SQL 문제] 연속된 숫자만 그룹핑하기 (0) | 2020.03.03 |
---|---|
테이블에 foreign key 컬럼 생성하는 법 (0) | 2020.02.20 |
[ORACLE] FUNCTION 생성: 숫자에 단위 표시(구분자로) & 숫자를 한글로 읽은 것 출력하는 함수 [FOR ~LOOP, IF - ELSE, CURSOR - FETCH] (0) | 2019.11.10 |
[ORACLE, ORANGE] TIP 모음 (0) | 2019.11.02 |
[Oracle, sqlplus, sql developer] 개발환경 설치 - 삽질 (TNS 에러, TNS 리스너, SID, .oRA 파일 에러 해결 방법 (0) | 2019.10.27 |
Comments