[오라클 10g] SQL Model절에 대하여 5 2 14,132

by 백해현 [풍요로운삶을] [2007.01.09 14:15:11]


새로운 MODEL 절

Jonathan Gennick

읽기 앞 서 - 열람을 위해서는 참조 목록을 봐야 합니다. 참조할 목록은 해당 구절에 링크를 생성시켰으니 참조하시기 바랍니다.

EX) "목록 1을 보자"라는 구절에서 "목록 1"을 누르면 해당 표를 보실 수 있습니다

새로운 MODEL 절을 사용하여 스프레드시트 계산을 데이타베이스로 가져옵니다.

계산된 열값을 반환하는 쿼리를 작성 중일 때 이 계산의 입력으로 여러 행의 값이 필요하다면 어떻게 하시겠습니까? 실제로 이 문제는 상당히 흔한 문제입니다.

대개 이 문제의 해결 방법은 자체 결합(self-join)과 하위 쿼리를 이해하기 어려운 방식으로 조합하여 사용하는 것입니다.

Oracle Database 10g에서는 새로운 접근 방식을 사용할 수 있습니다.

SELECT 문의 새로운 MODEL 절을 사용하여 관계형 데이타를 다차원 배열로 간주할 수 있으며 이 다차원 배열에 스프레드시트 형식의 계산을 사용할 수 있습니다.

이 결과 더 쉽게 쿼리를 개발하고 이해하며 수정할 수 있습니다.

시나리오

예를 들어, 출판업자인 여러분이 2002년과 2003년의 서적 매출을 바탕으로 2004년의 매출을 예측해야 한다고 가정해 보겠습니다.

미국과 캐나다에서 서적을 출판하며 월간 매출 데이타를 나타내는 다음과 같은 테이블이 있습니다.

CREATE TABLE book_sales (
isbn VARCHAR2(13),
country VARCHAR2(2),
year NUMBER,
month NUMBER,
gross_revenue NUMBER,
return_revenue NUMBER,
net_revenue NUMBER,
gross_units NUMBER,
return_units NUMBER,
net_units NUMBER);

다음 공식을 사용하여 2004년 매출을 예측하려고 합니다.

s4 = ((s3-s2)/s2)*s3+s3

이 공식은 2002년과 2003년 같은 달 사이의 매출 증가 또는 감소 비율을 계산합니다. 그 다음 이 비율을 2003년 매출에 적용하여 2004년 같은 달의 매출 예측치를 구합니다.

기본적인 전제는 2002년과 2003년 사이의 경향이 어떠했든지 간에 2004년에도 그대로 계속된다는 것입니다.

이 예측 작업에 어느 정도의 실제적인 복잡성을 더하기 위해, 2002년 1월자로 일부 서적이 절판되어서 총 24개월 동안 일부 서적의 매출 기록을 구할 수 없었습니다.

해당 월의 서적 매출 기록이 없는 경우는 해당 년도에서 매출 기록이 있는 모든 달의 평균 매출을 사용하여 예측 공식을 계산하려고 합니다.

또한 2003년도의 매출 정보는 아직 완벽하지 않으며 2003년 4/4분기의 매출 데이타는 없습니다.

이에 대처하기 위해 2003년 2/4분기에서 3/4분기까지 각 서적의 경향을 통해 4/4분기의 매출을 예측하여, 이 예측 매출을 4/4분기의 10월, 11월, 12월로 균등하게 나누려고 합니다,

마지막으로, 미국이 아닌 다른 국가의 매출 기록은 현지 통화로 기록되며 미국 달러화로 모든 국가의 매출을 예측하려고 합니다.

MODEL 절 입력

위에서 설명한 계산은 스프레드시트에서 매출을 모델링할 때 일반적으로 사용할 수 있는 것입니다.

여러분은 2004년 매출을 예측하는 데 사용할 모델을 만들고 있으며 다행히도 곁에 Oracle Database 10g가 실행되고 있습니다.

새로운 MODEL 절에 대해 방금 전에 읽어보았기 때문에 이 절을 예측 문제에 사용하기로 합니다.

MODEL 절을 사용하려면 자신의 데이타를 개념적으로 다차원 배열로 구성해야 합니다. 각 결과 집합 행이 이 다차원 배열의 셀이 됩니다.

모델을 만들기에 앞서, 이 모델을 별도의 배열로 파티션을 분할하는 방법과 그 여부에 대해 생각해 보십시오.

파티션 분할이 꼭 필요한 것은 아니지만 파티션을 분할하면 데이타베이스에서 병렬로 작업을 처리할 수 있으며 훨씬 더 쉽게 공식을 작성할 수 있습니다.

두 국가의 매출 데이타가 있는 경우 각 국가의 예측 매출은 다른 국가의 매출과 무관하므로 국가별로 파티션을 분할해야 합니다.

MODEL
PARTITION BY (country c)

그 다음, 데이타의 범위(dimension)를 지정해야 합니다. 즉, 배열의 특정 행을 고유하게 식별하기 위해 결합되는 값을 지정해야 합니다.

서적 매출 데이타의 경우, ISBN 번호, 년도 및 월로 범위를 지정해야 합니다. 이들 값은 각 국가의 배열에 있는 행을 고유하게 식별합니다.

MODEL
PARTITION BY (country c)
DIMENSION BY (isbn i, year y, month m)

모델의 각 셀에는 하나 이상의 값이 포함되지만 예측 공식에는 총수입값만 필요하므로 이 열 하나만을 예측값으로 나열합니다.

MODEL
PARTITION BY (country c)
DIMENSION BY (isbn i, year y, month m)
MEASURES (s.net_revenue r)

마지막으로, 규칙을 작성할 수 있으며 규칙은 예측값을 가지고 수행할 계산을 정의합니다.

예를 들어, 한 서적의 2004년 1월 총수입을 예측하는 데 초점을 맞춰 보겠습니다. 다음과 같은 공식으로 해당 셀을 참조합니다.


r["1-56592-948-9",2004,1]

이 셀 참조는 MEASURES 절에 지정된 별칭으로 시작합니다. 그 다음은 대괄호 안에 범위값의 목록이 나옵니다.

이 예는 위치적 참조를 나타나며, 이 경우 DIMENSION BY 절에 해당하는 순서대로 각 범위의 값을 나열합니다.

위치적 참조는 간결하며 이 참조를 사용하여 새로운 셀값을 삽입한 후 이 값을 쿼리 결과 집합의 새 행으로 변환할 수 있습니다.

기본적으로 MODEL 절은 오라클 호출 upsert 구문을 지원합니다.

이전에 없던 셀에 대해 범위를 지정하고 이 셀에 값을 할당할 경우, 데이타베이스는 범위, 예측값 및 파티션 데이타를 결합하여 결과 집합에 새 행을 만듭니다.

셀에 값을 할당하려면 다음과 같은 표기법을 사용합니다.

r["1-56592-948-9",2004,1] = value
r["1-56592-948-9",2004,1] = expression


목록 1은 한 서적의 2004년 매출을 예측하는 규칙이 포함된 완벽한 MODEL 절을 나타냅니다. 이 규칙은 앞에서 설명한 예측 공식을 구현합니다.

2002년과 2003년의 데이타를 사용하여 2004년의 예측값을 계산하므로 이 규칙에서 등호 기호 양쪽의 셀 참조를 볼 수 있습니다.

규칙을 말할 때 일반적으로 할당 연산자의 왼쪽에 있는 규칙과 오른쪽에 있는 규칙을 각각 “왼쪽” 및 “오른쪽”이라고 부릅니다.

목록 1의 쿼리의 경우 각 파티션에 대해 규칙이 한 번씩, 즉 국가마다 한 번씩 평가됩니다.

이렇게 해서 한 행에는 해당 서적의 2004년 1월 캐나다 매출이 들어가고 다른 행에는 같은 달의 미국 매출이 들어갑니다.

목록 1의 것과 같은 쿼리를 실행할 때 마지막으로 평가되는 절은 MODEL, SELECT 및 ORDER BY입니다.

MODEL 절에 열 별칭을 지정할 수 있으며, 별칭을 사용하면 계산을 더 정확하게 지정할 수 있기 때문에 저는 별칭을 지정하였습니다.

이 별칭은 SELECT 절에서 볼 때 열 이름이 되며, SELECT 절에서 별칭을 더 지정할 수 있습니다.

예측값 루프 반복

배열의 모든 셀에 데이타가 들어있도록 누락된 월간 매출 데이타를 채워야 합니다. 이를 위해 목록 2의 규칙 왼쪽에 다음과 같은 세 개의 FOR 루프를 사용할 수 있습니다.

FOR i IN (SELECT isbn FROM book)? to iterate over each ISBN number
FOR y FROM 2002 TO 2003 INCREMENT 1?to iterate over the two years
FOR m FROM 1 TO 12 INCREMENT 1? to iterate over the twelve months

CV() 함수는 FOR 루프를 유용하게 만들어 줍니다. 이 함수는 특정 범위의 현재값에 액세스하는 데 사용됩니다.

CV() 함수의 오른쪽에는 FOR 루프가 반복되는 값이 들어갑니다. 따라서 다음 셀 참조

[CV(), CV(), CV()]는

다음과 같이 됩니다.

[" 0-596-00441-9", 2002, 1]
[" 0-596-00441-9", 2002, 2]
[" 0-596-00441-9", 2002, 3]
...

upsert 구문은 필요에 따라 새로운 결과 집합 행을 만들도록 합니다. 목록 2의 쿼리를 실행하면 총 24개월 동안 각 서적의 월간 매출 행이 나타납니다.

일부 월간 매출 행이 데이타베이스에 존재하지 않더라도 이 행이 나타날 것입니다.

또한 규칙은 모델의 각 파티션에 무관하게 자동으로 적용되므로 각 국가에 대해 월간 매출 행이 나타날 것입니다.

목록 2의 CASE 문에 있는 새로운 IS PRESENT 술어는 특정 달의 총수입 데이타가 존재하는지 검사합니다.

MODEL 절에 의해 평가되는 초기 행 집합에 셀이 존재한다면 IS PRESENT가 True로 평가됩니다.

r의 값이 존재한다면 이 값이 nr에 복사됩니다. r의 값이 존재하지 않으면 nr은 해당 서적과 년도의 평균 매출로 설정됩니다.

r 자체를 CASE 문의 결과로 설정할 수 있었지만, r값을 새로 만들면 AVG(r)와 같은 합계 함수의 결과가 바뀔 가능성이 있습니다.

nr을 사용하면 다른 계산에 사용하도록 원래의 r(총수익)값을 보존할 수 있습니다.

목록 2의 AVG 함수는 다른 방식의 셀 어드레스를 제공합니다. 일련의 예측값에 대해 합계 함수를 실행할 때 사용되는 기본 형식은 다음과 같습니다.


AVG(expression)[dimension,
dimension...]

목록 2는 처음 두 범위에 대해 CV()를 사용하여 현재 서적과 년도의 값을 참조합니다. 그 다음 m BETWEEN 1 AND 12 술어를 사용하여 현재 서적과 년도의 모든 값을 고려하여 평균값을 계산합니다.

AVG 함수는 괄호 안에 식을 지정합니다. 열 참조의 경우 이 식이 지정 범위의 각 셀에 대해 평가됩니다. 그러면 AVG 함수는 이 평가의 평균값을 반환합니다.

규칙: 파티션 외부 병합 사용

MODEL 절을 사용할 때 자신이 작성한 규칙의 수를 알아야 합니다. MODEL 쿼리는 최대 10,000개의 규칙으로 제한됩니다. 하지만 규칙 수는 쿼리에서 반환되는 파티션값의 수와는 무관합니다. 따라서 모델에서 세 개의 규칙을 정의하면 쿼리가 2개의 파티션값을 반환하든 또는 20,000개의 파티션값을 반환하든 규칙은 세 개가 됩니다.
FOR 루프는 매크로와 유사하며 쿼리를 컴파일할 때 여러 개의 단일 셀 규칙으로 확장됩니다. 예를 들어, 2의 FOR 루프는 서적당 매달 1개씩 2년 동안 24개의 규칙을 생성합니다.

규칙 한도에 근접할 수 있는 모델을 만드는 경우, 다른 방법을 사용하여 규칙 수를 줄일 수 있습니다. 한 가지 방법은 규칙에서 하나 이상의 FOR 루프를 제거하고 FOR 루프의 범위 열을 PARTITION BY 절에 추가하는 것입니다.

목록 2 다른 방법은, Oracle Database 10g의 새로운 파티션 외부 병합(outerjoin) 구문을 사용하여 채워넣기(densification) 작업을 MODEL 절 외부로 꺼내서 MODEL 배열을 생성하기 전에 필요한 행을 만드는 것입니다. 이 예에서는 외부 병합 방법을 사용했습니다. 목록 2은 다음과 같은 외부 병합을 사용하여 월간 매출 데이타의 빈 부분을 채웁니다.

PARTITION BY (s.country, s.isbn)
RIGHT OUTER JOIN month mo
ON (s.month = mo.m AND s.year=mo.y)

목록 2의 월 테이블에는 2002, 2003, 2004년도의 각 달에 대해 하나씩 총 36개의 행이 있습니다. 3행의 PARTITION BY 절은 코드 작성과 이해를 쉽게 하기 위해 국가와 ISBN 번호의 각 조합에 대해 별도로 병합을 수행해야 한다고 지정합니다. 올바른 외부 병합으로 각 달의 결과가 보장됩니다. 이제 더 이상 2002년부터 2003년까지 MODEL에서 새 행을 만들지 않아도 됩니다. 따라서 규칙 왼쪽의 셀 참조를 FOR 루프에서 다음과 같은 ANY 술어로 변경할 수 있습니다.


nr[ANY, ANY, ANY] = ...

이 세 개의 ANY 술어는 서적, 년도, 월의 각 조합에 대해 규칙을 수행하도록 합니다. 목록 2의 결과는 목록 2의 결과와 동일하지만, FOR 루프에 의한 규칙 한도 초과가 발생하지 않습니다.

2004 매출 예측

이제 거의 끝났습니다. 하지만 우선 2/4분기와 3/4분기의 경향에 따라 2003년 4/4분기의 매출을 예측해야 합니다. 목록 2는 이 예측을 수행하는 규칙을 나타냅니다. 이 새 규칙은 다소 복잡해 보일 수 있지만 이전에 설명한 s4 = ((s3-s2)/s2)*s3+s3 공식을 확장한 것에 불과합니다. 이 규칙에서는 BETWEEN 술어를 사용하여 해당 분기의 셀을 분리합니다. 예를 들어, 다음 식은 현재 서적의 2003년 2/4분기 총매출을 반환합니다.

SUM(nr)[CV(), 2003, m BETWEEN 4 and 6])

목록 2는 또한 2004 매출을 예측하는 규칙을 나타냅니다. 이 규칙은 이전에 설명한 공식을 확장한 것입니다.

Next Steps
샘플 데이타 및 코드 다운로드
otn.oracle.com/oramag/oracle/04-jan/modeld.html
otn.oracle.com/oramag/oracle/04-jan/modelc.html

MODEL 쿼리 백서 읽기
otn.oracle.com/oramag/oracle/04-jan/model.html


통화 변환

마지막으로 통화 변환을 수행해야 합니다. 이를 위해 통화 변환 배율기가 들어있는 참조 테이블을 모델에 추가할 수 있습니다.
MODEL 키워드 뒤에 나오는 REFERENCE 절을 목록 5에서 찾아 보십시오.

참조 테이블은 또다른 다차원 배열에 불과합니다.
이 배열의 이름을 money라고 지정하고 국가 코드별로 범위를 지정했습니다.
이제 money.to_us[c]를 참조하여 해당 국가의 환율을 구할 수 있습니다.
모델의 각 셀에서 국가 코드를 사용할 수 있도록 목록 5는 국가 코드를 예측값 목록에 추가합니다.
파티션 또는 범위 열 또한 예측값이 될 수 있습니다.
목록 5는 다음과 같은 중첩된 셀 참조를 사용하여 각 셀에 적합한 환율을 구합니다.

money.to_us[cc[CV(),CV(),CV()]]

가장 안쪽의 셀 참조(별칭 cc의 셀 참조)는 현재의 국가 코드를 반환하며, 이 코드를 money 배열의 인덱스로 사용하여 환율을 검색합니다.
이 환율은 총수입을 미국 달러로 변환하는 데 사용됩니다.

새로운 MODEL 사용

MODEL 절을 통해 관계형 데이타를 다양한 방식으로 사용할 수 있습니다.
이제 데이타베이스 내에서 스프레드시트 형식의 계산을 수행할 수 있습니다.
규칙을 사용하면 다른 방식으로는 불가능한 의미를 명확하게 표현할 수 있습니다.
또한 변화하는 비즈니스의 요구 사항에 더 쉽게 반응할 수 있습니다.
MODEL 절과 파티션 외부 병합 기능을 함께 사용하여 수많은 쿼리 문제를 해결할 수 있는 독창적인 솔루션을 개발할 수 있습니다.


목록1
SELECT c, i, y, m, r
FROM book_sales s
WHERE s.year IN (2002, 2003)
MODEL
   PARTITION BY (country c)
   DIMENSION BY (isbn i, year y, month m)
   MEASURES (s.net_revenue r)
   RULES (
      r['1-56592-948-9',2004,1] = ROUND(
         ((r['1-56592-948-9',2003,1] - r['1-56592-948-9',2002,1])
           / r['1-56592-948-9',2002,1]) * r['1-56592-948-9',2003,1]
         + r['1-56592-948-9',2003,1],2))
ORDER BY c, i, y, m;


목록2
SELECT c, i, y, m, r, nr
FROM book_sales s
WHERE s.year IN (2002, 2003)
MODEL
   PARTITION BY (country c)
   DIMENSION BY (isbn i, year y, month m)
   MEASURES (s.net_revenue r, CAST(NULL AS NUMBER) nr)
   RULES (
      --Generate monthly sales for missing months (densification)
      nr[FOR i IN (SELECT isbn FROM book),
         FOR y FROM 2002 TO 2003 INCREMENT 1,
         FOR m FROM 1 TO 12 INCREMENT 1]
         = CASE WHEN r[CV(), CV(), CV()] IS PRESENT
              THEN r[CV(), CV(), CV()]
              ELSE ROUND(AVG(r)[CV(), CV(), m BETWEEN 1 AND 12],2)
           END
   )
ORDER BY c, i, y, m;

 

 

create table zz_temp_sales (
  ctry  varchar2(20),
  prod  varchar2(20),
  yr    number  (4),
  qty   number  (5)
);

insert into zz_temp_sales values ('Argentina', 'Table', 2002,  220);
insert into zz_temp_sales values ('Argentina', 'Table', 2003,  248);
insert into zz_temp_sales values ('Brazil',    'Table', 2002,  515);
insert into zz_temp_sales values ('Brazil',    'Table', 2003,  602);
insert into zz_temp_sales values ('Chile',     'Table', 2002,   29);
insert into zz_temp_sales values ('Chile',     'Table', 2003,   42);

insert into zz_temp_sales values ('Argentina', 'Chair', 2002,  115);
insert into zz_temp_sales values ('Argentina', 'Chair', 2003,  134);
insert into zz_temp_sales values ('Brazil',    'Chair', 2002,  297);
insert into zz_temp_sales values ('Brazil',    'Chair', 2003,  368);
insert into zz_temp_sales values ('Chile',     'Chair', 2002,   14);
insert into zz_temp_sales values ('Chile',     'Chair', 2003,   22);

insert into zz_temp_sales values ('Argentina', 'Phone', 2002, 1244);
insert into zz_temp_sales values ('Argentina', 'Phone', 2003, 1590);
insert into zz_temp_sales values ('Brazil',    'Phone', 2002, 8190);
insert into zz_temp_sales values ('Brazil',    'Phone', 2003,10844);
insert into zz_temp_sales values ('Chile',     'Phone', 2002, 3103);
insert into zz_temp_sales values ('Chile',     'Phone', 2003, 4965);

select
  ctry, prod, yr, qty
from
  zz_temp_sales
model
  partition by (prod, ctry)
  dimension by (yr)
  measures     (qty)
  rules (
    qty[2004] = qty[2003] * (qty[2003]/qty[2002])
  )
order by yr,ctry,prod;

CTRY                 PROD                         YR        QTY
-------------------- -------------------- ---------- ----------
Argentina            Chair                      2002        115
Argentina            Phone                      2002       1244
Argentina            Table                      2002        220
Brazil               Chair                      2002        297
Brazil               Phone                      2002       8190
Brazil               Table                      2002        515
Chile                Chair                      2002         14
Chile                Phone                      2002       3103
Chile                Table                      2002         29
Argentina            Chair                      2003        134
Argentina            Phone                      2003       1590
Argentina            Table                      2003        248
Brazil               Chair                      2003        368
Brazil               Phone                      2003      10844
Brazil               Table                      2003        602
Chile                Chair                      2003         22
Chile                Phone                      2003       4965
Chile                Table                      2003         42
Argentina            Chair                      2004  156.13913
Argentina            Phone                      2004 2032.23473
Argentina            Table                      2004 279.563636
Brazil               Chair                      2004 455.973064
Brazil               Phone                      2004 14358.0386
Brazil               Table                      2004 703.697087
Chile                Chair                      2004 34.5714286
Chile                Phone                      2004 7944.32001
Chile                Table                      2004 60.8275862

 

select dt
  from (select trunc(sysdate) dt from dual)
 model  dimension by (0 d)
        measures (dt)
        rules iterate(9)
              (dt[iteration_number+1] = dt[iteration_number] + 1)


-- Sample Data
SET ECHO OFF
PROMPT
PROMPT The following tables will be dropped and recreated by
PROMPT this script: BOOK, BOOK_SALES, CURRENCY, and MONTH.
PROMPT
PAUSE Press ctrl-c to stop, or any other key to continue...
PAUSE Are you really sure? Press ctrl-c to stop, any other key to continue...

SET ECHO ON
SET DEFINE OFF

DROP TABLE book;
DROP TABLE book_sales;
DROP TABLE currency;
DROP TABLE month;

CREATE TABLE month (
    m       NUMBER, y NUMBER);

INSERT INTO month VALUES (1, 2002);
INSERT INTO month VALUES (2, 2002);
INSERT INTO month VALUES (3, 2002);
INSERT INTO month VALUES (4, 2002);
INSERT INTO month VALUES (5, 2002);
INSERT INTO month VALUES (6, 2002);
INSERT INTO month VALUES (7, 2002);
INSERT INTO month VALUES (8, 2002);
INSERT INTO month VALUES (9, 2002);
INSERT INTO month VALUES (10, 2002);
INSERT INTO month VALUES (11, 2002);
INSERT INTO month VALUES (12, 2002);
INSERT INTO month VALUES (1, 2003);
INSERT INTO month VALUES (2, 2003);
INSERT INTO month VALUES (3, 2003);
INSERT INTO month VALUES (4, 2003);
INSERT INTO month VALUES (5, 2003);
INSERT INTO month VALUES (6, 2003);
INSERT INTO month VALUES (7, 2003);
INSERT INTO month VALUES (8, 2003);
INSERT INTO month VALUES (9, 2003);
INSERT INTO month VALUES (10, 2003);
INSERT INTO month VALUES (11, 2003);
INSERT INTO month VALUES (12, 2003);
INSERT INTO month VALUES (1, 2004);
INSERT INTO month VALUES (2, 2004);
INSERT INTO month VALUES (3, 2004);
INSERT INTO month VALUES (4, 2004);
INSERT INTO month VALUES (5, 2004);
INSERT INTO month VALUES (6, 2004);
INSERT INTO month VALUES (7, 2004);
INSERT INTO month VALUES (8, 2004);
INSERT INTO month VALUES (9, 2004);
INSERT INTO month VALUES (10, 2004);
INSERT INTO month VALUES (11, 2004);
INSERT INTO month VALUES (12, 2004);

COMMIT;

CREATE TABLE book (
    isbn        VARCHAR2(13),
    name        VARCHAR2(50));

CREATE TABLE book_sales (
    isbn            VARCHAR2(13),
    country         VARCHAR2(2),
    year            NUMBER,
    month           NUMBER,
    gross_revenue   NUMBER,
    return_revenue  NUMBER,
    net_revenue     NUMBER,
    gross_units     NUMBER,
    return_units    NUMBER,
    net_units       NUMBER);

CREATE TABLE currency (
    country         VARCHAR2(2),
    to_us           NUMBER);

INSERT INTO currency VALUES ('US',1);
INSERT INTO currency VALUES ('CA',0.74);

COMMIT;

INSERT INTO book VALUES ('0-596-00441-9','Oracle SQL*Plus Pocket Reference, 2nd Edition');
INSERT INTO book VALUES ('1-56592-948-9','Oracle SQL*Loader: The Definitive Guide');
--INSERT INTO book VALUES ('0-596-00601-2','Oracle Regular Expressions Pocket Reference');

COMMIT;

INSERT INTO book_sales VALUES ('0-596-00441-9','US',2002,10,18514.1,0,18514.1,3620,0,3620);
INSERT INTO book_sales VALUES ('0-596-00441-9','US',2002,11,8810.2,0,8810.2,1760,0,1760);
INSERT INTO book_sales VALUES ('0-596-00441-9','US',2002,12,32154.3,150.4,32003.9,5240,30,5210);
INSERT INTO book_sales VALUES ('0-596-00441-9','US',2003,1,19479.5,825.6,18653.9,3410,130,3280);
INSERT INTO book_sales VALUES ('0-596-00441-9','US',2003,2,8505.4,189.7,8315.7,1300,40,1260);
INSERT INTO book_sales VALUES ('0-596-00441-9','US',2003,3,16909.3,5327.8,11581.5,2670,920,1750);
INSERT INTO book_sales VALUES ('0-596-00441-9','US',2003,4,6977.1,216.2,6760.9,1110,30,1080);
INSERT INTO book_sales VALUES ('0-596-00441-9','US',2003,5,8394.2,2410.6,5983.6,1500,410,1090);
INSERT INTO book_sales VALUES ('0-596-00441-9','US',2003,6,4224.1,552.1,3672,650,140,510);
INSERT INTO book_sales VALUES ('0-596-00441-9','US',2003,7,8172.3,465.1,7707.2,1380,60,1320);
INSERT INTO book_sales VALUES ('0-596-00441-9','US',2003,8,3801,248.1,3552.9,590,30,560);
INSERT INTO book_sales VALUES ('0-596-00441-9','US',2003,9,6591.5,484.5,6107,910,60,850);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2002,1,24773.7,6150.6,18623.1,1750,360,1390);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2002,2,7444.4,5283.8,2160.6,440,350,90);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2002,3,5374.6,894.3,4480.3,280,50,230);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2002,4,4657.9,2571.3,2086.6,270,150,120);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2002,5,19540.6,10506.4,9034.2,1140,600,540);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2002,6,5806.2,8756,-2949.8,330,520,-190);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2002,7,11127.2,3012.8,8114.4,640,180,460);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2002,8,3050.6,598.4,2452.2,170,30,140);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2002,9,2407.8,735.5,1672.3,130,40,90);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2002,10,850.8,103,747.8,50,0,50);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2002,11,2567,1414.1,1152.9,150,90,60);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2002,12,5561.3,830.6,4730.7,330,50,280);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2003,1,6466.4,2038.7,4427.7,390,140,250);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2003,2,165.3,46,119.3,0,0,0);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2003,3,7664,1919.5,5744.5,450,140,310);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2003,4,10195.9,1606.9,8589,590,80,510);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2003,5,3342.8,280.5,3062.3,200,20,180);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2003,6,2428.7,1568,860.7,140,130,10);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2003,7,1211,171.4,1039.6,60,20,40);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2003,8,6508.1,2765.7,3742.4,360,210,150);
INSERT INTO book_sales VALUES ('1-56592-948-9','US',2003,9,3965,1240.1,2724.9,230,70,160);
--INSERT INTO book_sales VALUES ('0-596-00601-2','US',2003,9,17101.9,0,17101.9,11670,0,11670);
INSERT INTO book_sales VALUES ('0-596-00441-9','CA',2002,10,9257.05,0,9257.05,1810,0,1810);
INSERT INTO book_sales VALUES ('0-596-00441-9','CA',2002,11,4405.1,0,4405.1,880,0,880);
INSERT INTO book_sales VALUES ('0-596-00441-9','CA',2002,12,16077.15,45.12,16032.03,2620,9,2611);
INSERT INTO book_sales VALUES ('0-596-00441-9','CA',2003,1,9739.75,247.68,9492.07,1705,39,1666);
INSERT INTO book_sales VALUES ('0-596-00441-9','CA',2003,2,4252.7,56.91,4195.79,650,12,638);
INSERT INTO book_sales VALUES ('0-596-00441-9','CA',2003,3,8454.65,1598.34,6856.31,1335,276,1059);
INSERT INTO book_sales VALUES ('0-596-00441-9','CA',2003,4,3488.55,64.86,3423.69,555,9,546);
INSERT INTO book_sales VALUES ('0-596-00441-9','CA',2003,5,4197.1,723.18,3473.92,750,123,627);
INSERT INTO book_sales VALUES ('0-596-00441-9','CA',2003,6,2112.05,165.63,1946.42,325,42,283);
INSERT INTO book_sales VALUES ('0-596-00441-9','CA',2003,7,4086.15,139.53,3946.62,690,18,672);
INSERT INTO book_sales VALUES ('0-596-00441-9','CA',2003,8,1900.5,74.43,1826.07,295,9,286);
INSERT INTO book_sales VALUES ('0-596-00441-9','CA',2003,9,3295.75,145.35,3150.4,455,18,437);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2002,1,12386.85,1845.18,10541.67,875,108,767);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2002,2,3722.2,1585.14,2137.06,220,105,115);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2002,3,2687.3,268.29,2419.01,140,15,125);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2002,4,2328.95,771.39,1557.56,135,45,90);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2002,5,9770.3,3151.92,6618.38,570,180,390);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2002,6,2903.1,2626.8,276.3,165,156,9);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2002,7,5563.6,903.84,4659.76,320,54,266);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2002,8,1525.3,179.52,1345.78,85,9,76);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2002,9,1203.9,220.65,983.25,65,12,53);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2002,10,425.4,30.9,394.5,25,0,25);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2002,11,1283.5,424.23,859.27,75,27,48);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2002,12,2780.65,249.18,2531.47,165,15,150);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2003,1,3233.2,611.61,2621.59,195,42,153);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2003,2,82.65,13.8,68.85,0,0,0);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2003,3,3832,575.85,3256.15,225,42,183);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2003,4,5097.95,482.07,4615.88,295,24,271);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2003,5,1671.4,84.15,1587.25,100,6,94);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2003,6,1214.35,470.4,743.95,70,39,31);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2003,7,605.5,51.42,554.08,30,6,24);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2003,8,3254.05,829.71,2424.34,180,63,117);
INSERT INTO book_sales VALUES ('1-56592-948-9','CA',2003,9,1982.5,372.03,1610.47,115,21,94);

COMMIT;

SET DEFINE ON
SET ECHO OFF
  

by 박준하 [2007.01.26 12:40:01]
모처럼 들어 왔더니 새로운 내용이 있네요~ ^^

by 동동동 [2017.05.19 17:32:57]

감사합니다..^^

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입