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 값을 추가해보자..
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
결과 :
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의 부재가 아닌듯 싶다.
물론 직책상 역할자가 있었지만, 너무 개방적이고 개인들의 역량에 의존했던 나머지,
프로젝트가 채 정리도 되지 않은채 마무리 되어가고 있다.
차라리 내가 그 역할을 수행할 껄 그랫네 싶을정도로 아쉬었다.
다음 프로젝트 부터는, 개발방법론을 중요시하고, 개발해야 될것같다.
좋은 경험 했다.
원문 : http://mygony.com/archives/991
정확히 말하면 ECMA 스크립트의 특징이지만 뭐… ^^
첫번째, 객체의 생성
var arr = [];
var obj = {};
var str = "";
var arr1 = [1,2,3];
var obj1 = {prop1 : 'value1', "prop2" : 'value2'};
Object는 {} 로, Array는 []로 생성할 수 있다. object 를 생성할 때 property 의 이름은 따옴표를 따로 해주지 않아도 prop1의 경우처럼 그냥 사용할 수 있다. 하지만, 혹시라도 있을지 모르는 문제점(prop1이 변수로 선언되어있다던가 하는…)을 미리 방지하기 위해서 따옴표를 붙여주도록 하는게 좋다. 단, 충돌이 없음이 확실하다면 생략해도 무방하다.
두번째, object property의 접근
var obj = { "prop1" : "value1", "prop2" : "value2" };
alert(obj.prop1);
alert(obj["prop1"]);
. 으로 호출하는 방법, 문자열로 인덱스를 지정하는 방법. 둘 다 사용가능하다. 따라서 다음과 같은 것도 가능하다.
var i=2;
alert(obj["prop"+i]);
세번째, or 의 사용
var val = predefined_value || "value";
or 연산자로 연결된 값을 처음부터 비교해서 false와 동등하게 처리되는 값이 아니라면 반환한다. false와 동등하게 처리되는 값에는 undefined, null, 숫자0, false가 있다. 위 코드에서는 predefined_value 라는 변수가 정의되어있지 않으면 “value”이라는 값을 val 이라는 변수에 할당한다. 보통 IE와 FF의 이벤트 처리가 다른데 그럴 경우에 다음과 같이 사용하기도 한다.
function eventHandler(e) {
var evt = e || window.event;
// ... some code
}
네번째, 괄호()의 사용
(function(str){
alert(str);
})("str");
괄 호는 괄호안의 내용을 해석/실행해서 결과값을 리턴하는 역할이다. (1+2) 라고 하면 괄호는 1+2를 계산해 3 이라는 값을 리턴하는 것과 마찬가지라는 뜻. 따라서 위처럼 anonymous 함수를 만들어놓고 바로 실행할 수도 있게된다(괄호를 통해 함수객체가 반환되었기 때문).
이올린에 북마크하기
이올린에 추천하기

