50년후 대한민국은 인구수가 50% 이상 감소되고
이미 딴나라 정부는 일본에 임시정부를 차리고 모두 일본시민권자이다.
60년 후 대한민국은 인구수가 90% 이상 감소되어있고,
이미 국가를 유지할 모든 힘을 사실상 상실하게 되어..
대한민국은 일본의 속국이 된다..
이미 회생할수 없을만큼 오염이 되어버린 대한민국은 각종 폐기물
등을 매립하는 땅으로 바뀐다...
단군신화를 바탕으로 한 한민족의 문명은 5천년만에 역사속에서 자취를 감춘다.
select '1' as val from dual
union
select '2' as val from dual
)
select a.val, b.val from o a, o b
where a.val = b.val
결과 :
1, 1
2, 2
o 라는 가상 뷰테이블을 만들고 셀프조인으로 얻은 결과이다.
여기에 null 값을 추가해보자..
select '1' as val from dual
union
select '2' as val from dual
union
select '' as val from dual -- '' 대신 null 을 넣어도 결과는 같다.
)
select a.val, b.val from o a, o b
where a.val = b.val
결과 :
1,1
2,2
즉 null = {value} 의 비교는 성립되지 않는다...
많은 초보님들이 실수하는 것중에 하나가
null 을 눈에 보이지는 않지만 코드를 지니고 있는 무언가 로 착각한다.
그게 참이라면 분명히 결과가
1,1
2,2
{null}, {null}
처럼 나와야 할것이다...
null 인지 아닌지를 판단할 수 있는 비교문이 있다.
그게 바로 is NULL 과 is not NULL 이다.
즉 null 값을 가질 가능성이 있는 컬럼의 값에 대해서는
is null 이나 is not null 로 비교를 해줘야한다는 이야기이다.
위의 결과를 아래의 결과처럼 나오게 할려면 조건절이 분명 변경되어야한다.
with o as (
select '1' as val from dual
union
select '2' as val from dual
union
select '' as val from dual -- '' 대신 null 을 넣어도 결과는 같다.
)
select a.val, b.val from o a, o b
where a.val = b.val
or (a.val is null and b.val is null)
결과 :
1,1
2,2
{null}, {null}
--------------------- 마치며 ------------------------
일반 프로그래밍 언어처럼 value == null 처럼 비교되는 오류를 범할수있기에
몇자 적어봤습니다.
-- Create Pivot Table
CREATE TABLE COM_PIVOT
(
SEQ_ID NUMBER NOT NULL,
SEQ_NM VARCHAR2(5)
);
CREATE INDEX PKIDX_COM_PIVOT
ON COM_PIVOT (SEQ_ID);
ALTER TABLE COM_PIVOT
ADD PRIMARY KEY (SEQ_ID);
-- SQL for Lotto
-- by NalCo(tm) on 2008.3.
SELECT
GAME_SEQ,
ROW_SEQ,
MAX(CASE WHEN COL_SEQ = 1 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL1,
MAX(CASE WHEN COL_SEQ = 2 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL2,
MAX(CASE WHEN COL_SEQ = 3 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL3,
MAX(CASE WHEN COL_SEQ = 4 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL4,
MAX(CASE WHEN COL_SEQ = 5 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL5,
MAX(CASE WHEN COL_SEQ = 6 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL6,
MAX(CASE WHEN COL_SEQ = 7 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL7,
MAX(CASE WHEN COL_SEQ = 8 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL8,
MAX(CASE WHEN COL_SEQ = 9 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL9,
MAX(CASE WHEN COL_SEQ = 10 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL10,
MAX(CASE WHEN COL_SEQ = 11 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL11,
MAX(CASE WHEN COL_SEQ = 12 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL12,
MAX(CASE WHEN COL_SEQ = 13 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL13,
MAX(CASE WHEN COL_SEQ = 14 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL14,
MAX(CASE WHEN COL_SEQ = 15 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL15,
MAX(CASE WHEN COL_SEQ = 16 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL16,
MAX(CASE WHEN COL_SEQ = 17 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL17,
MAX(CASE WHEN COL_SEQ = 18 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL18,
MAX(CASE WHEN COL_SEQ = 19 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL19,
MAX(CASE WHEN COL_SEQ = 20 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL20,
MAX(CASE WHEN COL_SEQ = 21 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL21,
MAX(CASE WHEN COL_SEQ = 22 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL22,
MAX(CASE WHEN COL_SEQ = 23 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL23,
MAX(CASE WHEN COL_SEQ = 24 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL24,
MAX(CASE WHEN COL_SEQ = 25 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL25,
MAX(CASE WHEN COL_SEQ = 26 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL26,
MAX(CASE WHEN COL_SEQ = 27 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL27,
MAX(CASE WHEN COL_SEQ = 28 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL28,
MAX(CASE WHEN COL_SEQ = 29 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL29,
MAX(CASE WHEN COL_SEQ = 30 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL30,
MAX(CASE WHEN COL_SEQ = 31 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL31,
MAX(CASE WHEN COL_SEQ = 32 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL32,
MAX(CASE WHEN COL_SEQ = 33 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL33,
MAX(CASE WHEN COL_SEQ = 34 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL34,
MAX(CASE WHEN COL_SEQ = 35 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL35,
MAX(CASE WHEN COL_SEQ = 36 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL36,
MAX(CASE WHEN COL_SEQ = 37 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL37,
MAX(CASE WHEN COL_SEQ = 38 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL38,
MAX(CASE WHEN COL_SEQ = 39 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL39,
MAX(CASE WHEN COL_SEQ = 40 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL40,
MAX(CASE WHEN COL_SEQ = 41 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL41,
MAX(CASE WHEN COL_SEQ = 42 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL42,
MAX(CASE WHEN COL_SEQ = 43 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL43,
MAX(CASE WHEN COL_SEQ = 44 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL44,
MAX(CASE WHEN COL_SEQ = 45 AND NUM IS NOT NULL THEN NUM||SELECTED_YN ELSE NULL END) AS COL45
FROM (
SELECT
A.GAME_SEQ, A.ROW_SEQ, A.COL_SEQ,
A.NUM,
CASE WHEN B.NUM IS NULL THEN '' ELSE '√' END SELECTED_YN
FROM (
SELECT
CEIL(SEQ_ID /(CEIL(NC/CPRS)*CPRS))
AS GAME_SEQ,
CEIL(SEQ_ID / CPRS)
-((CEIL(SEQ_ID /(CEIL(NC/CPRS)*CPRS))-1)*CEIL(NC/CPRS))
AS ROW_SEQ,
(SEQ_ID - ((CEIL(NC/CPRS)*CPRS) * (CEIL(SEQ_ID /(CEIL(NC/CPRS)*CPRS))-1)))
-((CEIL(SEQ_ID / CPRS)
-((CEIL(SEQ_ID /(CEIL(NC/CPRS)*CPRS))-1)*CEIL(NC/CPRS)) -1)*CPRS)
AS COL_SEQ,
CASE
WHEN SEQ_ID-((CEIL(NC/CPRS)*CPRS)*(CEIL(SEQ_ID /(CEIL(NC/CPRS)*CPRS))-1)) > NC
THEN NULL
ELSE SEQ_ID - ((CEIL(NC/CPRS)*CPRS) * (CEIL(SEQ_ID /(CEIL(NC/CPRS)*CPRS))-1))
END
AS NUM
FROM COM_PIVOT A
CROSS JOIN (
SELECT
:PARAM_COLS_PER_ROWS AS CPRS,
:PARAM_GAME_CNT AS GC,
:PARAM_MAX_NUM AS NC
FROM COM_PIVOT
WHERE SEQ_ID=1
)B
WHERE SEQ_ID<=CEIL(NC/CPRS)*CPRS*GC
) A
LEFT OUTER JOIN (
SELECT GAME_SEQ, NUM FROM (
SELECT
GAME_SEQ,
NUM,
RANK() OVER (PARTITION BY GAME_SEQ ORDER BY ORDER_SEQ DESC) AS NUM_SEQ
FROM (
SELECT
CEIL(SEQ_ID /NC) AS GAME_SEQ,
SEQ_ID - NC*(CEIL(SEQ_ID /NC)-1) AS NUM,
DBMS_RANDOM.VALUE(1,100) AS ORDER_SEQ
FROM COM_PIVOT A
CROSS JOIN (
SELECT :PARAM_COLS_PER_ROWS AS CPRS,
:PARAM_GAME_CNT AS GC,
:PARAM_MAX_NUM AS NC
FROM COM_PIVOT
WHERE SEQ_ID = 1
) B
WHERE SEQ_ID <= GC*NC
)
) WHERE NUM_SEQ <= :MAX_SEL_NUM
) B
ON (A.GAME_SEQ = B.GAME_SEQ AND A.NUM=B.NUM)
)
GROUP BY GAME_SEQ, ROW_SEQ
ORDER BY GAME_SEQ, ROW_SEQ
;
10일만에 구현하면 비용이 줄어들거라고 생각한다.
개발은 10일 줄어들 지언정
프로젝트는 20일이 지나서 끝난다.
내일 일을 오늘한다고, 거시적으로
나아지는 건 전혀 없다..
오히려 무수한 쓰레기코드와
싸워야 할지도 모른다.
내일 할일을 일부러 오늘 할 필요는 없다.
내일의 일을 위해 우린 오늘 여유를 즐겨야 한다.
이번프로젝트에서 가장 아쉬운점은, PM/PL의 부재가 아닌듯 싶다.
물론 직책상 역할자가 있었지만, 너무 개방적이고 개인들의 역량에 의존했던 나머지,
프로젝트가 채 정리도 되지 않은채 마무리 되어가고 있다.
차라리 내가 그 역할을 수행할 껄 그랫네 싶을정도로 아쉬었다.
다음 프로젝트 부터는, 개발방법론을 중요시하고, 개발해야 될것같다.
좋은 경험 했다.
이올린에 북마크하기
이올린에 추천하기

