728x90
반응형

 

DB 프로그램 순서


1. 데이터베이스 설정 정보 준비
2. DB 접속하기 : 커넥션(connect)
3. 커서 받아오기 : cursor()
4. 구문 작성하기 : sql(조회, 입력, 수정, 삭제)
5. 구문 실행하기 :  execute() -> 결과값은 체크
6. 조회인 경우 커서에서 데이터 추출하기
        -> 한건 : fetchone()
        -> 여러건 : fetchall()
7. 조회결과 데이터프레임 또는 웹페이지에 출력
    -> 데이터프레임 : pd.DataFrame(여러건), pd.DataFrame([한건])
8. 조회가 아닌 경우 : 처리 결과 조건으로 확인하기 if "처리 성공" else "처리 실패"
9. DB정보 반환하기
        - 반환 순서 : cursor > connect
    

데이터 조회하기

🍀 데이터베이스 연결

import pymysql
### 접속 정보
# - 접속 허가를 위한 정보
# - 접속 id or 도메인
host = "localhost"
# - 사용자계정
user = "gjuser"
# - 패스워드
password = "dbdb"
# - 데이터베이스명
db = "gjdb"
# - 한글처리
charset = "utf8"
# - 조회시 컬럼명을 동시에 보여줄지 여부 설정
cursorclass = pymysql.cursors.DictCursor

 

🍀 DB 접속하기

  • connect로 서버에 연결 허가를 요청하여 conn에 허가를 받아 옴
try :
    conn = pymysql.connect(host = host,
                           user = user,
                           password = password,
                           db = db,
                           charset = charset,
                           # autocommit = autocommit,
                           cursorclass = cursorclass)
    print("DB접속 성공 >>> ", conn)
except :
    print("DB Server Checking...")

 

🍀 커서 받아오기

cur = conn.cursor()
cur

 

 🍀 Select 문 생성 후 DB에게 요청 및 응답 받기

  • execute가 "Select * from time_power_demand"라는 요청문을 서버에게 가지고 가서 그에 대한 답을 가져온다.
sql = "Select * from time_power_demand"
rs_cnt = cur.execute(sql)
print(f"{rs_cnt}건이 조회 되었습니다.")


🍀 조회결과가 여러 건인 경우

  • non 맵핑 방식
  • df.to_sql은 orm( object relation mapping, 객체 맵핑 방식)
  • cursorclass설정 시 딕셔너리 형태로 컬럼명과 같이 가져옴
  • cursorclass설정 안하면 튜플로 가져와서 컬럼명 없이 값만 나옴
    - [(), ()...] 
rows = cur.fetchall()
rows

 

🍀 조회결과 데이터프레임으로 출력

  • cursorclass설정을 안해서 컬럼명 없이 받아온 경우
    - ymd_power_df = pd.DataFrame(rows, columns=["ymd", "time", "power"]) 처럼 컬럼명 지정해서 코드 작성
ymd_power_df = pd.DataFrame(rows)
ymd_power_df

🍀 조회결과가 한 건인 경우

  • 한건 조회를 위한 sql 구문 생성하기
  • sql 구문 쓸 때 컴마 뒤에 띄어쓰기 꼭 하기
sql = """
        Select * From time_power_demand
        Where ymd = '2021-01-01'
            And time = '1시'
"""
sql
  • execute로 sql 구문을 DB서버에 요청하고, 결과 받아오기 
cur.execute(sql)

 

한 건의 결과가 나왔다는 의미

 

  • 받아오고 데이터 추출하기
row = cur.fetchone()
row

  • 데이터프레임에 담아서 보여주기
    - 데이터가 한 건만 추출 될 때는 딕셔너리 타입으로 추출되기 때문에 데이터프레임에 데이터를 담을 때는 리스트 타입으로 넣어야함
ymd_power_df = pd.DataFrame([row])
ymd_power_df

 

데이터 입력하기

🍀 입력을 위한 구문 생성하기

sql = """
    Insert Into time_power_demand(
        ymd, time, power
    ) Values (
        '2020-12-31', '24시', 1234
    )
"""
sql

 

🍀 구문 처리하고 결과 값 받아오기

  • 저장 요청 시에는 결과값이 숫자값으로 반환된다
    - 몇 건이 수행 됐는지 숫자값으로 나옴
rs_cnt = cur.execute(sql)
rs_cnt
print(f'{rs_cnt}건이 처리되었습니다')

 

🍀 처리가 잘 되었는지 확인하기

  • 0보다 크면 '1건이 입력되었습니다.' 출력
  • 0이하인 경우에는  "입력되지 않았습니다." 출력 
if rs_cnt > 0 :
    print(f'{rs_cnt}건이 입력되었습니다.')
else :
    print(f'입력되지 않았습니다')

 

데이터 수정하기

### ymd가 2020-12-31이고, 시간이 24시 인 행을 찾아서 power의 값을 5678로 수정하기

sql = """
        Update time_power_demand set power = 5679
        Where ymd = '2020-12-31'
            And time = '24시'    
"""
rs_cnt = cur.execute(sql)
if rs_cnt > 0 :
    print(f'{rs_cnt}건이 수정되었습니다.')
else :
    print(f'수정되지 않았습니다')

 

데이터 삭제하기

### ymd가 2020-12-31이고, 시간이 24시 인 행을 찾아서 삭제하기

sql = """
        Delete
        From time_power_demand
        Where ymd = '2020-12-31'
            And time = '24시'    
"""
rs_cnt = cur.execute(sql)
if rs_cnt > 0 :
    print(f'{rs_cnt}건이 삭제되었습니다.')
else :
    print(f'삭제되지 않았습니다')

데이터 조회 문제

🍀조회해보기

  • 한번도 구매한적이 없는 회원정보를 조회하기
  • 조회 컬럼 : 회원아이디, 회원이름
sql = """
    SELECT mem_id, mem_name
    FROM member
    WHERE not exists (SELECT cart_member FROM cart
WHERE cart_member = mem_id)
"""
rs_cnt = cur.execute(sql)
if rs_cnt > 0 :
    print(f'{rs_cnt}건이 조회되었습니다.')
else :
    print(f'조회되지 않았습니다')

  • 커서가 가지고 있는 결과 추출하여 데이터프레임 형식으로 나타내기
rows = cur.fetchall()
noMember = pd.DataFrame(rows)
noMember

 

종료하기

🍀커서 및 커넥션 정보 반납(종료)하기

try:
    cur.close()
    conn.close()
except :
    print("이미 모든 커서와 접속 정보가 반납되었습니다.")
728x90
반응형
728x90
반응형

데이터 설계하기


🫐 테이블 설계하기

  • 테이블명, 컬럼명, 컬럼타입, null 여부에 대한 정의가 필요함
  • 산출물
    - 테이블 정의서
    - ERD
    - 스크립트 명세서

🫐 테이블 정의서

  • 자료형 길이 설정 시 한글은 *2
  • double
    소숫점을 가지는 많은 양의 데이터
    정밀도를 요구하는 데이터
    소숫점 아래 값이 많은 데이터

 

🫐 스크립트 명세서

  • SQL에 그대로 작성하여 테이블 생성

Create Table time_power_demand(
	ymd varchar(10) NOT NULL,
   time varchar(4) NOT NULL,
	power DOUBLE NOT null
);

 

DB 연결하기

🫐 데이터 저장시에 유용한 라이브러리

  • sqlalchemy
  • 설치 : pip install sqlalchemy

🫐  데이터 저장시에 유용한 라이브러리

  • pymysql
  • 설치 : conda install -c conda-forge pymysql
  • 설치 : pip install pymysql

🫐 Database 연결하기

from sqlalchemy import create_engine

### 연결정보 작성
db_connection_info = "mysql+pymysql://gjuser:dbdb@localhost:3306/gjdb"

### Database 연결하기
db_connection = create_engine(db_connection_info)
db_connection

데이터 프레임을 Table에 저장시키기

🫐 컬럼명 수정

  • 데이터프레임의 컬럼명을 테이블의 컬럼명과 같게 수정
  • 특정 컬럼명만 수정하고자 할 때
    → df.columns = [{"년도" : "ymd"}]
# - 데이터프레임의 컬럼명 전체수정하기
df.columns = ["ymd", "time", "power"]
df


🫐 데이터 저장하기

df.to_sql(name="time_power_demand",
         con=db_connection,
         index=False,
         if_exists="append")

 

8760 rows 저장 완료

 

 

 

SQL 조회시 값이 들어가 있는 것을 확인할 수 있다.

 

 

 

 

 

 

 

 

 

 

 


🫐 데이터베이스 자원 반환(접속 끊기)

  • 연결 종료하기
db_connection.dispose()

데이터 조회하기

🫐 데이터 조회

  • 조회시에는 pymysql 라이브러리 사용

🫐데이터베이스 연결

import pymysql
### 접속 정보
# - 접속 허가를 위한 정보
# - 접속 id or 도메인
host = "localhost"
# - 사용자계정
user = "gjuser"
# - 패스워드
password = "dbdb"
# - 데이터베이스명
db = "gjdb"
# - 한글처리
charset = "utf8"
# - 조회시 컬럼명을 동시에 보여줄지 여부 설정
cursorclass = pymysql.cursors.DictCursor

 

🫐 DB 접속하기

  • connect로 서버에 연결 허가를 요청하여 conn에 허가를 받음
try :
    conn = pymysql.connect(host = host,
                           user = user,
                           password = password,
                           db = db,
                           charset = charset,
                           # autocommit = autocommit,
                           cursorclass = cursorclass)
    print("DB접속 성공 >>> ", conn)
except :
    print("DB Server Checking...")

 

🫐 커서 받아오기

cur = conn.cursor()
cur

 

🫐 Select 문 생성 후 DB에게 요청 및 응답 받기

  • execute가 "Select * from time_power_demand"라는 요청문을 서버에게 가지고 가서 그에 대한 답을 가져 
sql = "Select * from time_power_demand"
rs_cnt = cur.execute(sql)
print(f"{rs_cnt}건이 조회 되었습니다.")

 

🫐 커서 및 커넥션 정보 반납(종료)하기

try:
    cur.close()
    conn.close()
except :
    print("이미 모든 커서와 접속 정보가 반납되었습니다.")
728x90
반응형
728x90
반응형

데이터 수집하기


🫐 한국전력거래소 시간별 전력수요량 데이터 수

  • 수집위치 : data.go.kr
  • 한국전력거래소 시간별 전력수요량 csv 파일 다운로드

 

데이터 불러들이기

🫐 데이터 프레임 변수명 : df

  • df = pd.read_csv(file_path)
    → 이렇게 작성하면 UnicodeDecodeError 에러
    → 인코딩 필요
  • pandas는 기본적으로 utf-8
  • 메모장 저장될 때 기본 utf-8, 공공데이터 저장 ansi
  • euc-kr 한국어 타입으로 인코딩
import pandas as pd
file_path = "./01_data/한국전력거래소_시간별 전력수요량_20211231.csv"
df = pd.read_csv(file_path, encoding= "euc-kr")
df

 

🫐 결측데이터 확인

df.info()

 

- 결측치는 없다

 

 

 

 

 

 

 

 

 

 

 

 

 

🫐 이상치 데이터 확인
- 측정된 데이터 이므로 min을 보는게 적절하다
- min이 0 이하로 떨어지면 이상치

df.describe()


🫐 컬럼명의 시간을 데이터화 하기 위하여 컬럼명 추출하기

df.columns

 

🫐 변수로 받기

col_list = df.columns
col_list

 

데이터 프레임 생성하기

 

🫐 3개의 열 (년도, 시간, 전력량)을 가지는 데이터프레임 생성하기

result_df = pd.DataFrame(columns=["년도", "시간", "전력량"])
result_df


🫐데이터프레임에 데이터 행단위 추가하기

  • items() : 튜플로 만들어서 넘겨주면 그 안에 갯수만큼 왼쪽의 변수들이 각각 받아준다.
  • print(ymd, "/", time, "/", value) : 2021-12-31 / 24시 / 70123 까지 추출된다.
  • concat() : 데이터프레임과 데이터프레임을 행단위(axis = 0) 또는 칼럼단위(axis = 1)로 추가할 때 사용
  • ignore_index=True : 행이 추가될 때 행 인덱스 번호를 자동증가 시키기 (default = false)
### 데이터프레임에 데이터 행단위 추가하기
result_df = pd.DataFrame(columns=["년도", "시간", "전력량"])

for index, row in df.iterrows() :
    # print(row)
    ### 년도 데이터
    ymd = row[col_list[0]] # 날짜
    
    ### 시간과 전령량이 합쳐진 데이터
    data = row[col_list[1:]] # 1시 부터 24시 까지. 모든 시간대
    # print(data)

    ### 시간과 전력량을 각각 추출하여 데이터프레임에 넣기
    # - 넣을 값 : 날짜, 시간, 잔력량
    for time, value in data.items() :
        # print(ymd, "/", time, "/", value)

        ### 행단위로 데이터프레임에 추가하기 위해서 추가할 행을 데이터프레임으로 생성
        df_temp = pd.DataFrame({"년도":[ymd], "시간":[time], "전력량":[value]})

        ### 데이터프레임에 행단위로 추가하기
        result_df = pd.concat([result_df, df_temp], axis=0, ignore_index=True)
        
### 최종결과 출력
result_df


       

🫐 정제된 데이터 파일로 저장하기

  • 저장할 경로 지정
  • index=False : 인덱스 번호값은 저장하지 않기(default = True)
save_path = "./01_data/new_data.csv"
result_df.to_csv(save_path, index = False)

좌) index = True 우) index = False 

🫐 저장한 데이터 파일 읽어들이기

file_path = "./01_data/new_data.csv"
df = pd.read_csv(file_path)
df

728x90
반응형
728x90
반응형

판다스(Pandas)

 

    • 행렬 데이터를 처리하기 위한 다양한 함수를 지원하는 라이브러리
    • 파일 읽기, 저장, 행렬데이터 처리, 기본 시각화 등 지원
    • 데이터 전처리 과정에서 주로 사용됨

데이터 분석과정

 

  • 데이터 수집 > 데이터 전처리 > 데이터 가공(필요시 전처리) > 데이터 분석 탐색/시각화(필요시 전처리) > 필요시 모델 훈련(머신러닝 or 딥러닝) > 웹서비스 또는 분석 보고서
  • 책에 나온 일반적인 과정 : 데이터수집 > 전처리 > 분석 > 시각화로 설명되고 있다.
  • 분석과정은 회사에 따라 다르다.

판다스(Pandas) 설치

 

  • Anaconda Prompt에서 pip list로 pandas 설치 확인

  • jupyter notebook에서 import
import pandas as pd
  • 사용되는 데이터 파일 - 노란색 부분

 

컬럼 : 국적코드, 성별, 입국객수, 전년동기

행은 0행 부터 시작한다.

즉, 노란색 부분을 추출하려면 A열에서 C열, 1행에서 7행만 추출한다.

 

 

 

 

 

 

 

데이터 수집 시 확인 사항

 

  • 날짜 확인 : 기준일로 사용
    - 년월일시분이 나타나 있는게 좋다.|
    - 최소한 년월까지는 있어야 한다. 최소 12개의 데이터를 확보할 수 있기 때문이다.
  • 범주형 데이터 확인 : 예로 남자 또는 여자와 같은 데이터
    - 범주형 데이터가 많은 데이터가 좋다. 비교대상이 많아 지기 때문이다.
    - 비교대상이 많아지면 데이터로 보여줄 수 있는게 많아진다

데이터 읽어오기

 

  •  파일 위치 지정
    - 상대경로로 지정한다.
file_path = "./files/sample_1.xlsx"
  • 피일 데이터 추출하기
    - file_path : 파일지정(위치 포함)
    - header : 칼럼명으로 사용할 행의 위치(default - 0)
    - skipfooter : 행의 가장 밑에서부터 포함하지 않을 행의 갯수(default - 0)
    - usecols : 가지고 올 열의 범위(A분터 C까지의 열)(default - data가 있는 모든 열)
sample_1 = pd.read_excel(file_path,
                        header=1,
                        skipfooter=2,
                        usecols="A:C")

 

  • csv, excel, json많이 사용
  • csv는 순수한 text 파일로 처리 과정이 따로 안들어가서 가볍다. 즉, 용량을 더 많이 담을 수 있다.
  • excel 파일 자체에 다양한 처리 과정이 같이 들어가기 때문에 무겁다.

 

 

 

 

 

  • 데이터 조회하기
sample_1

 

  • DataFrame 정보 확인하기
    - DataFrame 타입 : 행렬을 저장 관리하는 타입
    - info()함수는 데이터의 결측치(nan,null) 데이터 확인 가능
    - RangeIndex : 전체 행(row)의 갯수 0 to 5 총 6개
    - 전체 행의 갯수와 각 컬럼의 갯수가 안맞으면 결측 데이터가 존재한다는 의미.
sample_1.info()

 

# Non-Null = not null null이 아닌 데이터의 갯수
#  Dtype = 데이터 타입
#  object 문자열
# int 숫자

0 to 5 총 6개

 

 

 

 

 

  • 데이터프레임 출력
    - 데이터 행/열이 많은 경우 -> 기본 상위 5개, 하위 5개를 추출해서 보여줌
    - 데이터 행/열의 갯수가 작으면 모두 보여줌

  • head() : 상위 데이터 조회
    - 상위 5개
    sample_1.head()​

    - 상위 1개
    sample_1.head(1)​

 

  • tail() : 마지막 데이터 조회
    - default : 5개
    - 하위 5개
    sample_1.tail()​

    - 하위 1개
    sample_1.tail(1)​

  • 기초 통계 데이터
sample_1.describe()

 

- count : 데이터 행의 갯수
- mean : 데이터 평균
- std : 표준편차
- min : 최솟값
- max : 최댓값
- 25%, 50%(중앙값), 75% : 4분위수 데이터
        → 4분위수 데이터를 이용해서 이상치(이상한) 데이터 확인

- 기초통계 데이터는 숫자값을 가지는 컬럼에 대해서만 확인

 

 

 

데이터 조회하기

 

  • key 입력하고 value 받아오기
    - 국적코드 데이터 조회하기
sample_1["국적코드"]

 

- dtype: object

  → 데이터 하나하나의 타입이 object이다.

 

 

 

 

 

 

  • 타입 확인
    - 데이터 전체의 타입
type(sample_1["국적코드"])

 

- Series : 튜플과 모양이 같다. (사용법도 동일)
- {"국적코드" : (데이터, 데이터, ...)}

 

 

 

  • 2차원 행렬 형태로 조회
sample_1[["국적코드"]]

type(sample_1[["국적코드"]])

 

- [[ ]] : 2차원의 행렬인 DataFrame 타입

 

 

 

  • 국적코드와 성별 모두 조회하기
    - 컬럼 2개이상 조회시 [[ ]] 2차원 행렬 형태로 조회해야함
sample_1[["국적코드","성별"]]

 

 

기준년월 컬럼 추가하기

 

  • 2019-11 값을 추가하기
sample_1["기준년월"] = '2019-11'
sample_1

데이터 필터링 하기

 

  • 필터링 : 조건에 맞는 값 조회하기
  • 성별 중에 여성인 데이터만 추출하기
condition = sample_1["성별"] == "여성" 
condition


  • default 값은  True
sample_1[condition == False]


  • 한 줄로 조회하기
sample_1[(sample_1["성별"] == "여성") == True]

 


  • 객체 주소 전달 방식
    - 둘다 같은 곳을 바라 본다
    - sample_1이 바뀌면 sample_2가 바뀌고 sample_2가 바뀌면 sample_1이 바뀜
sample_2 = sample_1

 

  • copy()
    - 메모리 복제방식 (신규로 동일하게 생성 됨)

    - 신규로 만들어진 메모리 주소를 받아옴 (서로 영향 안받음)
    - 주소를 넣는 방식이 아니라 메모리를 복제하는 방식
sample_2 = sample_1.copy()
728x90
반응형
728x90
반응형

🎄사용자  정의 함수

  • 상품테이블에서 아래 컬럼 조회하기
    - 서브쿼리 사용 (join 사용하지 않기)
    - 조회컬럼 : 상품명, 상품분류명, 상품분류코드
 SELECT prod_name
 	, (select lprod_nm FROM lprod WHERE lprod_gu = prod_lgu) AS lprod_nm
    	, prod_lgu
 FROM prod;

 

  • 상품분류명을 추출하는 함수 생성하기
    - IF문으로 NULL값 있는지 확인
    - Delimiter 뒤에는 무조건 띄어쓰기
    - 문자열이 맞지 않아서 CHARACTER SET UTF8MB4 적용
 -- 함수 구문 시작
Delimiter //

-- 사용자 정의함수
CREATE FUNCTION udfGetLprodNm(paramGu VARCHAR(10))

-- 리턴타입 정의
RETURNS VARCHAR(50) CHARACTER SET UTF8MB4

-- 함수 기능 시작
BEGIN
	
	-- 반환할 값을 저장할 변수 선언
	DECLARE result VARCHAR(50) CHARACTER SET UTF8MB4;

	-- 상품분류명을 추출하는 sql구문 작성
	SELECT lprod_nm INTO result
	FROM lprod
	WHERE lprod_gu = paramGu;
	
	-- 조회결과가 있는지 확인
	if result IS NULL then
	 SET result = 'null';
	END if;
	
	-- 반환하기
	RETURN result;
    
-- 함수 기능 종료
END //

-- 함수 전체 구문 종료
Delimiter ;

  •  생성한 함수 호출하여 처리하기
SELECT prod_name
	,defGetLprodNm(prod_lgu) AS lprod_nm
    	,prod_lgu
FROM prod;

 

위에서 서브쿼리를 사용하여 작성한 코드와 동일한 결과

찾은 행 74 개

 

 

 

 

 

 

 

 

 

사용자 함수 정의 문제

문제 1

  • 회원이름, 성별 조회하기
  • 성별은 남성, 여성으로 조회
  • 함수 이름 : udfGetMenWomen
  • udfGetMenWomen 함수 정의
    - 남성 / 여성 추출하기
Delimiter //

CREATE FUNCTION udfGetMenWomen(paramNum INT)

-- 리턴 타입 정의
RETURNS VARCHAR(4) CHARACTER SET UTF8
BEGIN
	-- 반환할 변수 선언
	DECLARE result VARCHAR(4) CHARACTER SET UTF8;
	
	-- 남여 구분을 위한 조건문 처리
	if MOD(SUBSTRING(paramNum, 1, 1), 2) = 0 THEN
		SET result = '여성';
	ELSE 
		SET result = '남성';
	END if;

	RETURN result;
	
END //

Delimiter ;

 

 

  • 생성한 함수 호출하여 처리하기
SELECT mem_name
, udfGetMenWomen(mem_regno2) AS gender
FROM member;


문제 2

  • 새로운 주문이 발생했을 때 신규주문번호를 발급하는 함수 생성하기
  • 함수이름 : udfGetNewCartNo()
  • udfGetNewCartNo 함수 정의
Delimiter //

CREATE FUNCTION udfGetNewCartNo(paramNum VARCHAR(50))

RETURNS VARCHAR(50) CHARACTER SET UTF8

BEGIN
	DECLARE result VARCHAR(50) CHARACTER SET UTF8;
	
	if SUBSTRING(paramNum,1,8) = CURDATE() then	
		set result = paramNum + 1;
	ELSE
		SET result = concat(DATE_FORMAT(CURDATE(),'%Y%m%d'),'00001');
	END if;
	
	RETURN result;

END //

Delimiter ;

 

  • 생성한 함수 호출하여 처리하기
SELECT udfGetNewCartNo(MAX(cart_no)) AS newnum
FROM cart;

 



  • udfGetNewCartNo 함수 정의 - 강사님 
--
Delimiter //

CREATE FUNCTION udfGetNewCartNo()

RETURNS VARCHAR(13) CHARACTER SET UTF8

BEGIN
	DECLARE result VARCHAR(13) CHARACTER SET UTF8;
	
	SELECT if (MAX(cart_no) IS NOT NULL,
					MAX(cart_no) + 1,
						CONCAT(replace(CURDATE(), '-', ''),
								'00001')) INTO result
													
	FROM cart
	WHERE SUBSTRING(cart_no, 1, 8) = CURDATE();
	
	RETURN result;

END //

Delimiter ;

 

  • 생성한 함수 호출하여 처리하기 - 강사님
SELECT udfGetNewCartNo();

🎄View

  •  VIEW : 가상테이블
  • 자주 사용되거나, SQL 구문이 긴 경우 조회 목적으로만 사용
  • 미리 객체화 시켜서 테이블 처럼 사용하는 방식
  • 조회만 가능하며, 입력/수정/삭제가 되지 않는다.
  • 입력/수정/삭제가 되는 경우도 있지만, VIEW 사용 목적에 맞지 않는다.
  • 구매 내역이 없는 회원 조회하기
    - 조회 컬럼 : 회원아이디, 회원이름
SELECT mem_id, mem_name
FROM member
WHERE mem_id NOT in (SELECT cart_member FROM cart);

  • 구매내역이 없는 회원 view 생성
Delimiter //

CREATE VIEW viewNoCartMember AS

-- 조회할 select문 생성
SELECT mem_id, mem_name
FROM member
WHERE mem_id NOT in (SELECT cart_member 
FROM cart)//

Delimiter ;
  • view 사용하기
    - 사용법 : 테이블과 동일
SELECT *
from viewNoCartMember;

🎄저장 프로시저(Stored Procedure; sp)

  • 프로그램 영역이 아닌, DB자체에서 SQL구문을 관리하고자 할 때 사용
  • 데이터베이스에 SQL구문을 객체화하여 호출방식으로만 사용하는 방식

  • 구매내역이 없는 회원 프로시저 생성
Delimiter //

CREATE Procedure spNoCartMember()
Begin

-- 조회할 select문 생성
SELECT mem_id, mem_name
FROM member
WHERE mem_id NOT in (SELECT cart_member 
FROM cart);

END //
Delimiter ;
  • 프로시저 호출하기
call spNoCartMember();

 

VIEW / 저장 프로시저 문제

문제 1

  • 모든 거래처별 매출 금액의 총합 조회하기
  • 단, 2005년도 주문내역
  • 조회컬럼 : 거래처 코드, 거래처명, 매출금액의 총합
  • 위 조회에 대한 select문을 view로 생성
  • 프로시저에서 위에 생성한 view를 사용하여 call
  • view이름 : viewGetBuyerAll
  • 프로시저이름 : spGetBuyerAll

  • viewGetBuyerAll VIEW 생성
Delimiter //

CREATE VIEW viewGetBuyerAll AS

	-- 조회할 select문 생성
	SELECT buyer_id
			, buyer_name
			, SUM(NVL(prod_sale*cart_qty,0)) AS total
	FROM buyer
		LEFT JOIN prod
			ON (buyer_id = prod_buyer)
		LEFT JOIN CART
			ON (prod_id = cart_prod 
					AND cart_no LIKE '2005%')
	GROUP BY buyer_id, buyer_name//

Delimiter ;

 

  • spGetBuyerAll 프로시저 생성
Delimiter //

CREATE procedure spGetBuyerAll()
begin

	-- 조회할 select문 생성
	SELECT buyer_id
			, buyer_name
			, SUM(NVL(prod_sale*cart_qty,0)) AS total
	FROM buyer
		LEFT JOIN prod
			ON (buyer_id = prod_buyer)
		LEFT JOIN CART
			ON (prod_id = cart_prod 
					AND cart_no LIKE '2005%')
	GROUP BY buyer_id, buyer_name;
	
END //	

Delimiter ;

 

  • VIEW / 프로시저 호출
SELECT *
FROM viewgetbuyerall;

CALL spGetBuyerAll();

 

 

🎄저장 모듈(Stored Module)

  •  SQL 문장을 데이터베이스 서버에 저장하여 사용자와 애플리케이션 사이에서 공유할 수 있도록 만든 일종의 SQL 컴포넌트 프로그램이며, 독립적으로 실행되거나 다른 프로그램으로 부터 실행될 수 있는 완전한 실행 프로그램이다. Oracle의 저장 모듈에는 Procedure, User Defined Function, Trigger가 있다.

  • Procedure와 Trigger의 차이점
Procedure Trigger
CREATE Proceduer 문법사용 CREATE Trigger 문법사용
EXECUTE 명령어로 실행 생성 후 자동으로 실행
COMMIT, ROLLBACK 실행 가능 COMMIT, ROLLBACK 실행 안됨

 

728x90
반응형
728x90
반응형

문제

  • 가장 최근에 입고된 상품의 상품명, 거래처명
  • 가장 최근에 입고된 상품을 가장 많이 구매한 회원의 아이디, 이름, 마일리지, 해당 상품 구매수량, 회원등급 구하기
  • 조회 컬럼 : 상품명, 거래처명, 회원아이디, 회원이름, 마일리지, 해당 상품 구매수량, 회원 등급
  • 등급 조건
마일리지 등급
~ 999 아이언
1000 ~ 1999 브론즈
2000 ~ 2999 실버
3000 ~ 3999 골드
4000 ~ 4999 플래티넘
5000 ~  다이아
  • ERD

작성한 코드

코드 1

SELECT  AA.prod_name, AA.buyer_name, AA.mem_id, AA.mem_name, AA.mem_mileage, AA.cart_qty,
(CASE
        WHEN AA.mem_mileage BETWEEN 1000 AND 2000 THEN '브론즈'
        WHEN AA.mem_mileage BETWEEN 2000 AND 3000 THEN '실버'
        WHEN AA.mem_mileage BETWEEN 3000 AND 4000 THEN '골드'
        WHEN AA.mem_mileage BETWEEN 4000 AND 5000 THEN '플래티넘'
        WHEN AA.mem_mileage >= 5000 THEN '다이아'
    	ELSE '아이언'
	 END) AS grade 
FROM (
	SELECT prod_name, buyer_name, mem_id, mem_name, mem_mileage, cart_qty, cart_prod
   	FROM member, cart, prod, buyer
    		WHERE mem_id = cart_member
            AND cart_prod = prod_id
            AND prod_buyer = buyer_id 
      ) AA,
     (
	SELECT cart_prod, MAX(cart_qty) AS cart_qty
		FROM cart
    		WHERE cart_prod IN (
           				 SELECT B.buy_prod
           					 FROM (SELECT MAX(buy_date) AS max_date
                  					FROM buyprod) A,
                 					(SELECT buy_prod, buy_date
                  					FROM buyprod) B
            					WHERE A.max_date = B.buy_date)
    			GROUP BY cart_prod ) BB
	WHERE AA.cart_prod = BB.cart_prod 
      AND AA.cart_qty = BB.cart_qty
	ORDER BY prod_name;

 

 

코드 2

출처 미니 조코딩 님

https://sujakjil.tistory.com/54

SELECT prod_name ,buyer_name ,mem_id , mem_name , mem_mileage , cart_qty ,
      (case 
      when mem_mileage BETWEEN 1000 AND 1999 then '브론즈'
      when mem_mileage BETWEEN 2000 AND 2999 then '실버'
      when mem_mileage BETWEEN 3000 AND 3999 then '골드'
      when mem_mileage BETWEEN 4000 AND 4999 then '플래티넘'
      ELSE '다이아' 
      END) AS 'grade'
FROM member , cart , prod , buyer
WHERE prod_id = cart_prod
AND mem_id = cart_member
AND prod_buyer = buyer_id
AND prod_id IN (SELECT prod_id FROM buyprod , prod 
               WHERE prod_id = buy_prod
               AND buy_date = (SELECT MAX(buy_date)
               FROM buyprod))
AND cart_qty in (SELECT  MAX(cart_qty)
FROM cart , prod
WHERE cart_prod = prod_id
and prod_id IN (SELECT prod_id FROM buyprod , prod 
               WHERE prod_id = buy_prod
               AND buy_date = (SELECT MAX(buy_date)
               FROM buyprod))
GROUP BY prod_id);

결과

728x90
반응형

+ Recent posts