'전체 글'에 해당되는 글 384건

  1. 2020.10.23 인터넷
  2. 2020.10.21 Why is ORDER BY in a FROM Subquery Ignored?
  3. 2020.10.15 끄적2
  4. 2020.08.25 favicon.ico 404 Not found 에러
  5. 2020.08.21 MYSQL INSERT UPDATE (ON DUPLICATE KEY)
  6. 2020.07.31 Map vs. Array
  7. 2020.07.15 6일차 JavaScript
  8. 2020.06.29 Maven Project War파일 만들기 ~ 개발서버 배포
  9. 2020.06.24 mysql - 프로시저
  10. 2020.06.23 고쳐야할것, 실수 끄적여놓은 것들

인터넷

|

<IP와 도메인>
- 우리가 알고있는 홈페이지 주소들은 결국 IP주소로 변환이 되어야 함. 이를 가능케 해주는 것이 DNS임

<IPv6>
- 기존 IP(IPv4)는 0.0.0.0.~255.255.255.255. 총 42억개만 사용가능. 이미 수요 초과임.
- 이를 해결하기 위해 등장한 방법들(1/2/3)
1. IPv6 : 훨씬 복잡함. 2^128까지 IP주소 생성 가능. 단 기존 IPv4가 적용된 것들은 적용이 어려움... 현재 동시 사용 중

<포트>
2. 사설IP/공인IP : 공인IP의 가격문제로, 공유기를 통해 여러대의 기기 연결이 가능함. 이 때 개별 기기는 사설IP를 가지게 되는데, 이는 공인IP 내에서만 유효함. 이 사설IP를 가진 기기에 외부연결을 위한 기능이 포트포워딩임.
- 포트는 서버의 문이라고 이해하면 됨. 각 포트안에 웹서버가 설치되어 있음. 'IP주소:nn' 입력 시, 'nn'포트에 접속하는 것임

<포트포워딩>
- 공유기는 공인IP를 받음(WAN 꽂는 자리). 나머지 LANx는 사설IP를 가지고 있음.
- 사설IP를 외부로 연결시키기 위해 포트포워딩을 통해 공인IP 접속하면 특정 사설IP로 연결하도록 설정할 수 있음.

<절대경로, 상대경로>
- 절대경로: '/'만 쓰면 최상위 경로를 의미함(절대경로지만, IP가 바뀐다면 상대경로?!)
- 상대경로: '..'/'.' 을 통해, 부모/현재 디렉토리 기준으로 상대경로 설정 가능
- 기본(대문)페이지: 기본IP 주소만 입력하면 IP주소/index.html이 기본으로 열림. index.php를 열게 하기위해서는 index.html을 삭제하면 됨

<유동IP와 DDNS>
3. 통신사가 제공하는 IP는 계속 바뀜. Dynamic Address. 통신사가 한정적으로 IP를 가지고 있기 때문에, 사용하지 않을 때 회수했다가 새로 부여하는 방식임.
- 이를 해결하기 위한 DDNS(Dynamic DNS): 사용자는 도메인네임으로 접속할 뿐 IP는 모름. DDNS는 도메인과 호스트 IP를 동기화해주는 기능을 제공.

'IT Infra' 카테고리의 다른 글

PUTTY  (0) 2023.03.31
JWT(JSON Web Token)  (0) 2023.03.29
개발 환경 구성  (0) 2023.03.29
MSA 학습  (0) 2023.03.29
AWS 배포방법  (0) 2019.12.23
And

Why is ORDER BY in a FROM Subquery Ignored?

|

MySQL의 서브 쿼리에서의 order by는 경우에 따라 무의미하다.

 

MySQL은 서브쿼리의 결과 순서를 따로 메모리에 적재해 놓지 않기에 서브쿼리의 order가 메인쿼리에서는 무시됨.

 

따라서,

 

SELECT @rownum:=@rownum+1 as num, x.*
FROM (SELECT  col1, col2
             FROM TABLE1
           ORDER BY col2
           LIMIT 18446744073709551615
) X,
(SELECT @rownum:=0) r

위와 같이

서브쿼리에 LIMIT를 정해 주는 것으로 원하는 결과를 얻을 수 있다고 한다.

출처: https://amnesis.tistory.com/17 [달바라기]

출처: https://mariadb.com/kb/en/why-is-order-by-in-a-from-subquery-ignored/

'DATABASE(SQL)' 카테고리의 다른 글

Dual 테이블이란?  (0) 2021.04.19
프로시저, 트랜잭션, 배치  (0) 2021.04.16
MYSQL INSERT UPDATE (ON DUPLICATE KEY)  (0) 2020.08.21
mysql - 프로시저  (0) 2020.06.24
전자정부 프레임워크에 트랜잭션 적용하기  (2) 2020.03.31
And

끄적2

|
더보기

 

 

 

 

주니어 때 놓칠 수 있는 것 중 하나는 ‘큰 그림’을 보는 것이다.

사실 처음 주어지는 업무는 이미 만들어진 시스템의 일부를 유지보수 하거나 기능을 추가하는 업무이다.
그렇기 때문에 큰 그림을 놓칠 수가 있는데,
더 발전하는 개발자가 되기 위해서는 ‘큰 그림’을 보며 작은 것을 바꾸더라도 ‘큰 그림’에 어울리게 바꾸어야 한다.
그래야만 더 좋은 ‘큰 그림’을 그릴 수 있다.

 

'etc' 카테고리의 다른 글

M/M (Man Month) 이란?  (0) 2020.10.28
끄적3  (0) 2020.10.28
고쳐야할것, 실수 끄적여놓은 것들  (0) 2020.06.23
경로 표기법  (0) 2020.04.17
트러블 슈팅이란?  (0) 2020.04.07
And

favicon.ico 404 Not found 에러

|
<link rel="icon" href="data:;base64,iVBORw0KGgo=">

해당 jsp에 삽입하면 해결됨

 

favicon.ico 는 브라우저 아이콘을 가리킴.

출처 : https://stackoverflow.com/questions/31075893/im-getting-favicon-ico-error

'JavaScript' 카테고리의 다른 글

Coding Convention  (0) 2021.04.02
성능 향상을 위한 자바스크립트 코딩 패턴  (0) 2020.10.29
Map vs. Array  (0) 2020.07.31
formData, XMLHttpRequset, HTTP Content-Disposition  (0) 2020.06.01
일반for문 vs. for in문  (0) 2020.05.28
And

MYSQL INSERT UPDATE (ON DUPLICATE KEY)

|
1. 조건 : unique key
UNIQUE KEY `명칭` (`field1`,`field2`) 로 create table
field1, field2 는 unique key로 묶고자 하는 컬럼

2. 쿼리
INSERT INTO SSP_ATD
				(
					field1
                    ...
				)
				VALUES
				(
					#{value1}
                    ...
				)
				ON DUPLICATE KEY UPDATE
					field1 = #{value1}
                    ...
				;
                
3. unique key가 겹칠경우 아래의 update 구문을 수행함!
And

Map vs. Array

|

Map : object 형식으로 바로 index 찾을 수 있음... -> deep copy 활용

 

Array : index를 알아야 찾을 수 있음.

And

6일차 JavaScript

|

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">

/* 20.07.15 추가사항 */
==(동등연산자), !=(부등연산자) -> 자료형이 일치하지 않는 경우, 자료형을 일치시킨후 비교함.
===(일치연산자), !==(불일치연산자) -> 자료형변환없이, 엄격히 비교함.
so, ===(일치연산자), !==(불일치연산자) 을 사용하자!!!

/*비교연산자*/
/*0 ''(공백) false의 비교는 true(같다고 인식이 됨)*/
	alert('' == false); // true
	alert('' == 0); // true
	alert(0 == false); // true
	alert('273' == 273); // true , 비교시 숫자로 변환
	alert(0 == null); // false
	alert(0 == undefined); // false
	alert(null == undefined); // true, 직접 비교시 결과다름.
	
/*일치연산자 : 자료형과 값 일치여부 -> 자료형과 값이 모두 일치*/
	alert('' === false); // false
	alert('' === 0); // false
	alert(0 === false); // false
	alert('273' === 273); // false
	alert(null === undefined); // false
	
/*if조건문*/
	var date = new Date();
	var hour = date.getHours();

	if(hour<11){
		alert('아침 먹을 시간입니다.');
	} else if(hour<15){
		alert('점심 먹을 시간입니다.');
	} else{
		alert('저녁 먹을 시간입니다.');
	}
	
/*switch 조건문*/
	
	var input = Number(prompt('숫자를 입력하세요.', '숫자'));
	
	switch(input % 2){
		case 0:
			alert('짝수입니다.');
			break;
		case 1:
			alert('홀수입니다.');
			break;
		default:
			alert('숫자가 아니올시다.');
			break;
	}
	
/* for반복문 */
	var array = ['포도', '사과', '바나나', '망고'];
	
	for(var i = array.length - 1; i>=0; i--){
		alert(array[i]);	
	}

/* for in 반복문 */
	var array = ['포도', '사과', '바나나', '망고'];
	
	for(var i in array){
		alert(array[i]);	
	}
	
/*while 반복문*/
	var value = 0;
	var startTime = new Date().getTime();
	
	while(new Date().getTime() < startTime + 1000){
		value++;
	}
	
/*For문 예제 - label */
	outerloop:
	for(var i =0; i<10; i++){
		innerloop:
		for(var j = 0; j < 10; j++){
			if(j > 3) break;
			if(i == 2) break innerloop;
			if(i == 4) break outerloop;
			console.log("i=" + i + "j=" + j);
		}
	}
	console.log("Final i = " + i + "j = " + j);
	
/*  배열의 내장함수 */
	var array = ['포도', '사과', '바나나', '망고'];
	/*forEach : 각각의 function 기능을 각각 실행 - for문대신 써도됨.*/
	array.forEach(function(item){
		console.log(item);
	});	
	
/*Symbol.iterator 속성을 가지는 컬렉션 전용*/
	for(var i of array){
		alert(i);
	}
	
/*기존 기능에 영향을 주지 않으면서 새로운 property 추가*/
	var mySymbol1 = Symbol('mySymbol');
	var mySymbol2 = Symbol('mySymbol');
	mySymbol1 === mySymbol2; //false
	var prop2 = Symbol('prop2');
	var obj = {
			prop1: 1,
			[prop2]: 2,
	};
	for(var key in obj){
		console.log(key); // prop1만 출력됨
	}
	obj[prop2]; // 2, 대괄호[]로만 접근가능
	
/* 배열예제 1*/
	var arrayA = [0,1,2,3];
	arrayA.push(4); // 맨뒤에 추가
	arrayA.pop(); // 맨뒤항목 제거 후 반환
	arrayA.unshift(-1); // 맨앞에 추가
	arrayA.shift(); // 맨앞에 항목제거 후 반환
	delete arrayA[0]; // 첫번째 요소를 undefined로 변환 -> object에서는 속성제거
	
	arrayA.splice(1,2); //인덱스 1위치에서 2개의 항목제거
	arrayA.splice(1,2, 'four', 'five'); // 항목을 제거하고 2개의 항목을 인덱스 1에 추가
	
	var arrayB = [4, 5, 6];
	var arrayC = arrayA.concat(arrayB); // array 연결하기
	var arrayD = arrayB.slice(1,2); // 원본은 유지하고 인덱스 1에서 2개의 항목으로 배열을 만들어 리턴
	
/* 배열예제 2*/
	var numbers1 = ["apple", 1, 2, 3];
	var numbers2 = numbers1.map(myFunction); // 함수로직을 반영한 새로운 배열을 리턴
	var numbers3 = numbers1.filter(myFunction); // 함수가 true인 요소들의 새로운 배열을 리턴
	var numbers4 = numbers1.every(myFunction); // 모든 요소가 함수의 조건을 만족하는지 check, some 존재
	var a = numbers1.indexOf("apple"); // 0, lastIndexOf 존재
	document.getElementById("demo").innerHTML = "Apple is found in a position" + a;
	
	document.getElementById("demo").innerHTML = numbers2;
	function myFunction(value, index, array){
		return value *2;
	}
	
	document.getElementById("demo").innerHTML = numbers3;
	function myFunction(value, index, array){
		return value > 18;
	}
	
	document.getElementById("demo").innerHTML = numbers4;
	function myFunction(value, index, array){
		return value > 18;
	}
	
/* 배열예제 3*/
	var arrayA = ['b', 'c', 'a'];
	arrayA.sort(); //정렬하기 - 함수넣을수 있음. comparable과 같다고 보면 됨.
	arrayA.reverse(); // 역순으로 정렬하기
	arrayA.sort(function(a,b){return a - b}); // 정렬기준 함수를 매개변수로 전달
	
	var txt=""; // 전역변수
	var numbers = [0, 1, 2];
	numbers.forEach(myFunction); // 각요소별 함수호출
	numbers.first(myFunction); // 함수조건을 만족하는 첫번째 요소값, findindex존재(index 리턴)
	
	document.getElementById("demo").innerHTML = txt;
	function myFunction(value, index, array){ // value(요소), array(전체배열)
		txt = txt + value + "<br>";
	}
	
	//배열처럼 작동하는 유사배열을 내부적으로 많이 사용
	var a = {};
	// 1. 유사배열을 만들기 위해 property 추가
	var i = 0;
	while(i < 10){
		a[i] = i * i;
		i++;
	}
	a.length = i;
	//2. 실제 배열인 것처럼 사용
	var total = 0;
	for(var j=0; j<a.length; j++)
		total+= a[j];
	
// 메소드를 변수로 넘긴다!!!!!!!!	
//	1. 배열a의 각 원소중 filter함수를 만족하는 요소만을 새로운 배열로 리턴
	function filterArray(/*array*/a, /*Boolean function*/predicate){
		var results = [];
		var length = a.length; // 술어 함수가 배열의 길이를 반환할 경우에 대비하여
		for(var i =0; i<length; i++){
			var element = a[i];
			if(predicate(element)) results.push(element);
		}
		return results;
	}

//	2. 배열 a의 각 원소를 지정된 함수f로 전달하여 얻은 결과들을 원소로 하는 배열을 반환
	function mapArray(/*array*/a, /*function*/f){
		var r = [];
		var length = a.length; //함수 f가 배열 길이를 변환할 경우에 대비하여
		for(var i = 0; i < length; i++) r[i] = f(a[i]);
		return r;
	}

//	3. 피라미드 출력하기: alert or console.log 사용

	function pyramid(){
	var max = 10;
	for(var i = 0; i <= max; i++) {
		var print = "";
		for(var j = max; j>i; j--) {
				print+=" ";
		}
		for(var j = 0; j<2*i - 1; j++) {
				print+="*";
		}
		console.log(print);
      }
    }
	pyramid()

// 함수예제
// 함수를 전역변수에 할당
	function square(x){return x*x;}
	var a = square(4);
	var b = square; // b는 함수를 가리킨다.
	var c = b(5); // 자바스크립에서는 틀린 문법이 아님.
	
// 함수를 객체property에 할당
	var o = new Object();
	o.square = function(x){return x*x;}
	var y = o.square(16);
	
// 배열원소에 함수 할당
	var a = new Array(3);
	a[0] = function(x){return x*x;}
	a[1] = 20;
	a[2] = a[0](a[1]);
	
// 객체의 property를 배열로 전달
	function copyPropertyNamesToArray(o, a){
		if(!a) a = []; // if구문이고 많이 쓰임. 요걸로 대체가능 ( a = a|| []; ) 
        // !a는 !undefined 이므로 true임.
        // ||연산자: 첫번째가 true거나 true로 반환되는 값이면
        // 반환 아니면 두번째 반환
		for(var property in o) a.push(property);
		return a;
	}
	
// 함수를 데이터로 사용하기(많이 쓰는 함수들이므로 알아두면 좋다....)
	function add(x,y){return x+x;}
	function subtract(x,y){return x-x;}
	function muptiply(x,y){return x*x;}
	function divide(x,y){return x/x;}
	//위의 함수를 전달인자로 받아서 사용 -> 한줄로 끝낸다는 javascript의 장점 -> 많이쓰일수밖에 없다...
	function operate(operator, operand1, operand2){
		return operator(operand1, operand2);
	}
	
    // 객체로 구성하기
	var i = operate(add, operate(add, 2, 3), operate(multiply, 4, 5));
	var operations = {
			add: function(x,y){return x+y;},
			subtract: function(x,y){return x-y;},
			muptiply: function(x,y){return x*y;},
			divide: function(x,y){return x/y;},
			pow: Math.pow // 이미 정의된 함수도 사용
	}
	function operate2(op_name, operand1, operand2){
		if(typeof operators[op_name] == 'function'){
			return operators[op_name](operand1, operand2);
		} else throw 'unknown operator'; // 알수없는 연산자
	}
	var j = operate2('add', 'hello', operate2('add', '', 'world'));
	var k = operate2('pow', 10, 2);

// 메소드로서의 함수
	var calculator = {
		operand1: 1;
		operand2: 1;
		// 함수는 this라 property를 통해 자신이 속한 객체에 접근할 수 있다.
		compute:function(){
			this.result = this.operand1 + this.operand2;
		}
	};
	calculator.compute();
	console.log(calculator.result); // 결과를 출력
	
// 함수 property: length => 정의된 함수 매개변수 갯수
	function check(args){
		var actual = args.length; // 실제로 전달받은 매개변수 갯수
		var expected = args.callee.length; // 함수가 기대하는 매개변수 갯수
		// arguments.callee 는 함수 자기자신을 가리킴(문법)
		if(actual != expected){
			throw new Error('Wrong number of arguments');
		}
	}
	
	function f(x,y,z){
		//함수가 기대하는 전달인자를 받았는지 검사
		check(arguments);
		return x+y+z;
	}
	
// 함수 property 추가하기
	//함수의 정적property를 생성하고 초기화
	uniqueInteger.counter = 0;
	//호출할때 마다 다른 값을 리턴
	function uniqueInteger(){
		return uniqueInteger.counter++;
	}
	
// 객체 property를 전달인자로 사용하기(개발방식 중 하나)
	function arraycopy(from, from_start, to, to_start, length)
	function easycopy(args){
		arraycopy(args.from, args.from_start || 0, args.to, args.to_start || 0, args.length);
	}
	
</script>
</head>
<body>

	<p id="demo"></p>
	<button type="button" onclick="document.getElementById('demo').innerHTML=over18">Click !</button>

</body>
</html>

/*For문 예제 - label */

'Bitcamp > BITCAMP - Front Web' 카테고리의 다른 글

IBSheet 그리드 특강  (0) 2019.09.26
미니 프로젝트  (0) 2019.09.17
12일차 jQuery  (0) 2019.09.16
11일차 jQuery  (0) 2019.09.11
JavaScript - LinkedList, nodeType(재귀), Event 핸들러, DOM  (0) 2019.09.10
And

Maven Project War파일 만들기 ~ 개발서버 배포

|

 

* 20/06/29 추가

export - war file로 하면 제대로 배포가 안되는듯하고,

run - run configurations로 들어가야함.

 

1. Goals 부분에 clean package 입력

2. apply 누르고 run 누르면 해당 프로젝트 target 폴더에 .war 파일 생성됨

3. .war 파일 C:\tomcat9\webapps 에 넣은후, tomcat 실행(이클립스 서버 끈 상태에서)

4. http://localhost:8090/mavenTest/index.jsp 접속

 

 

'Bitcamp > BITCAMP - Spring FW' 카테고리의 다른 글

8일차  (0) 2019.10.17
7일차  (0) 2019.10.15
6일차  (0) 2019.10.11
5일차  (0) 2019.10.10
4일차  (0) 2019.10.08
And

mysql - 프로시저

|

 

/* 처음과 끝의 delimiter는 감싸고 있는 부분이 연속적으로 실행될 수 있게 하는 역할을 한다. */
delimiter $$

/* 기존에 procedure가 있다면 삭제 */
DROP PROCEDURE if exists mydb.TestProcedure$$

/*
    procedure를 생성하는 구문. procedure의 형식을 선언한다.
    in은 전달받는 parameter, out은 결과값을 담아 보낼 parameter
*/
CREATE PROCEDURE mydb.TestProcedure(in num INT, in str varchar(20))

/* procedure의 내용은 begin과 end로 감싼다. */	
BEGIN

        /* 
            procedure 내부에서 사용할 수 있는 변수를 선언한다.
            err 라는 변수를 선언하였으며 기본값을 0으로 선언했다.
            SQLEXCEPTION이 발생한 경우 err에 -1을 set 하도록 선언했다.
        */
        DECLARE err INT default '0';
	DECLARE continue handler for SQLEXCEPTION set err = -1;

        DECALRE result INT default '0';

	start transaction;
        
        /* 테스트로 임의의 테이블(primarytest)에 insert를 수행. */
	insert into primarytest(
            num1, num2, str1, str2
        )values(
            num, num*2, str, concat(str,' by primary')
        ); /* 성공 */
        
        insert into primarytest(
            num1, num2, str1, str2
        ) values(
            str, str, num, num
        ); /* int형 대신 str값을 넣어 오류를 유도. 실패 */
        
        /* SQLEXCEPTION 발생으로 인해 err 값이 -1로 setting이 되어 rollback이 수행된다. */
        if err < 0 then
    	    rollback;
        else
    	    commit;
        end if;
        
        /* 실패했기 때문에 아무것도 조회되지 않을 것이다. */
        select num1, num2, str1, str2
        from primarytest

       /* select 한 결과를 바로 result에 저장한다. */
        select sum(num1) into result
        from primarytest
        
END$$

delimiter
;


BEGIN NOT ATOMIC -- 세션에 활성 트랜잭션이 없는 경우 새 트랜잭션을 시작

-- 예외 발생시 롤백 후 Error 반환
DECLARE EXIT HANDLER FOR SQLEXCEPTION -- 에러 캐치시 handler의 begin ~ end 블럭을 실행
BEGIN
  ROLLBACK;
  RESIGNAL; -- error condition 정보를 Stored Procedure를 호출한 클라이언트에게 전합니다.
END;

-- 현재 자동 커밋인 경우에만 트렌젝션 처리 추가
SET @IS_AUTOCOMMIT = @@AUTOCOMMIT;
IF @IS_AUTOCOMMIT = 1 THEN
	START TRANSACTION;
END IF;

IF @IS_AUTOCOMMIT = 1 THEN
	COMMIT;
END IF;

END;
And

고쳐야할것, 실수 끄적여놓은 것들

|
6/23 

1. if 간소화 ( || || || ) ; -> 코드가 훨씬 간결해짐. a or b or c a가 true면 뒤쪽은 확인안함.

2. actionMap, bindUI는 함수로 간결하게 작성하고, 비즈니스 로직은 함수화 하도록 한다.

3. array 지속적 스캔 -> map을 활용 할 것.

4. 하나하나 하면서 커밋하는 습관을 가질 것.

마리아DB root/tiger

******************** 부서, 구성원 관리 정의 ********************

2-1. 사원이 처음 입사하고 등록시 history 테이블에 무조건 추가하게 된다.
->  부서장급을 추가하면 조직도에 뜨게된다.
- 단, 해당 추가된 사원이 부서장일 경우, DEPT 테이블 에서도 부서장으로 등록이 되어 있어야함.
- 추가된 사원이 팀원 급일 경우, --> DEPT 테이블과는 무관함.
 
2-2. 부서관리에서 부서를 생성 후 부서장 등록시, 
-> 해당 부서장 emp_no의 history_enddate 가 없는 이력을 찾아서 history_enddate를 sysdate로 넣어주고(update), 새로운 부서의 이력을 insert 해준다.
-> 이미 부서장(사원)의 history는 만들어진 상태이므로 이력이 있을수 밖에 없다.
-> update의 경우 : 1) 부서장 변경 -> history 종료 insert 필요
2) 종료일자 변경(부서 폐쇄) ->  history 종료 insert 필요 
그 외에는 dept 테이블만 update 처리
3) 상위부서변경 -> 상위부서코드만 변경
******************** SQL ********************

-- 시스템 포맷터 확인
SELECT * FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT';
  
-- 세션 값 수정
alter session set nls_date_language='KOREAN';

-- 조인 예시
SELECT a.emp_cd
     , DECODE(a.position, '임원', a.emp_cd, b.emp_cd) up_emp_cd
  FROM t_emp_info a
 INNER JOIN
       (SELECT o.seq_dept
             , REGEXP_SUBSTR(
               RTRIM(SYS_CONNECT_BY_PATH(e.emp_cd, ' '))
               , '[^ ]+$') emp_cd
          FROM t_organ_tree o
          LEFT OUTER JOIN
               (SELECT seq_dept
                     , MIN(emp_cd) emp_cd -- 부서 대표 임원 1명만
                  FROM t_emp_info
                 WHERE position = '임원'
                 GROUP BY seq_dept
                ) e
            ON o.seq_dept = e.seq_dept
         START WITH o.up_seq_dept IS NULL
         CONNECT BY PRIOR o.seq_dept = o.up_seq_dept
        ) b
    ON a.seq_dept = b.seq_dept
 ORDER BY emp_cd
;

-- 소속부서 이력 가져오는 쿼리
select d.dept_name || '(' ||  history_startdate ||'~'|| history_enddate || ')'
from history h, dept d
where h.dept_no = d.dept_no
and h.emp_no = 20009
order by history_no

-- t로 묶어서 쿼리 조회하는 예시
select d.dept_name
from dept d, (select h.dept_no
                from dept d, history h
                where d.dept_no = h.dept_no) t
where d.dept_no = t.dept_no

-- 시간 차 구하는 쿼리
SELECT 
  (  
    to_date('2013-08-01 21:01', 'yyyy-mm-dd hh24:mi')
    - to_date('2013-08-01 09:00', 'yyyy-mm-dd hh24:mi')
  ) * 24 -- 시간단위로변환
  AS min_diff
FROM DUAL

-- interval 커럼에 차이 나오는 작동되는 쿼리
SELECT systimestamp - tm AS interval
     , EXTRACT(DAY    FROM systimestamp - tm) *24*60*60
     + EXTRACT(HOUR   FROM systimestamp - tm) *60*60
     + EXTRACT(MINUTE FROM systimestamp - tm) *60
     + EXTRACT(SECOND FROM systimestamp - tm) AS second
FROM (SELECT TO_TIMESTAMP('20/02/28 09:40:33.751000000', 'yy/mm/dd hh24:mi:ss.ff') tm FROM dual)

-- 최종 이력 데이터에서 마지막 값 가져오는거 작동함
SELECT MAX(ATT_DATE) KEEP (DENSE_RANK LAST ORDER BY ATT_DATE)
FROM ATT
GROUP BY EMP_NO
******************** Review ********************

1. 조직도
- 직급의 크기 크게  > 완료★
- 전체적인 글씨크기 크게 -> 가독성  > 완료★
- 시트테마 적용(장차장님) > 완료★
-> 폰트패밀리로 변경(Arial,Tahoma,sans-serif)

2. 범례
- 기타 항목 추가하고, 전체인원 카운트도 포함시켜서  -> 완료★

4. att 데이터
-> 다른사람들도 세팅해놓아라.... -> 완료★
->  att db 데이터 장차장님께 전달(insert) -> 완료★ -> data.go.kr  에서 정보 확인(중소기업업체)

5. 조직도 팝업
-> 선 맞추기  -> 완료★

6. att(근태관리)
-> 사원선택 팝업 크기 조절 -> 완료★
-> 리셋버튼 없애기 -> 완료★ 
-> 조회 - 엑셀 - 추가 - 저장 버튼 순으로 바꾸기( 구성원관리, 부서관리도 해당) > 완료★

7. emp
-> 부서팝업 높이 체크 -> 완료★

8. dept
-> 부서명 좌측정렬 -> 완료★
-> 부서팝업 높이 체크 -> 완료★
-> 보조자 값 -> combo로(좌측 우측값으로 보여지게), 재직여부도 변경처리 완료 -> 완료★

'etc' 카테고리의 다른 글

끄적3  (0) 2020.10.28
끄적2  (0) 2020.10.15
경로 표기법  (0) 2020.04.17
트러블 슈팅이란?  (0) 2020.04.07
코딩을 잘하는 사람들의 특징  (0) 2020.01.21
And