피보나치 수열이란?


피보나치 수열은 앞의 두 개의 수를 더한 값을 다음 값으로 넣는 방식이다.


예를 들어 다음과 같이 리스트에 숫자 2개 0,1 이 있다고 해보자.

그다음 숫자는 0과 1을 더한 1이 리스트에 추가된다. 그다음 숫자는 1과 1을 더한 2가 리스트에 추가된다.


0, 1 then  0+1 = 1 


then 0, 1, 1


0, 1, 1 then 1+1 = 2


then 0, 1, 1, 2


0, 1, 1, 2 then 1+2 = 3


then 0, 1, 1, 2, 3 ...


이런 방식으로 추가하면 다음과 같은 리스트가 될 것이다.


0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765 ...


피보나치 수열 구현하는 방식을 두 가지 방법으로 표현하였다.


1. Binary Recursive (이진 재귀)

2. Tail-end Recursive (꼬리 재귀)





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package test1;
 
public class Pibonachi {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyFib1 myfib1 = new MyFib1();    
        System.out.println("myfib1 value: "+myfib1.fib(5));
        
        MyFib2 myfib2 = new MyFib2();
        System.out.println("myfib2 value: "+myfib2.fib(5));
        
    }
}
 
 
// 피보나치 수열 두가지 방법
 
// 1. Binary Recursive 이진 재귀
// f(n) = f(n - 1) + f(n - 2) 재귀 함수를 두번 실행 
class MyFib1{
    public int fib(int n) {
        if (n < 2){
            return n;
        }else{
            System.out.println("call fib("+(n-1)+")"+"+"+"call fib("+(n-2)+")");
            return fib(n - 1+ fib(n - 2); 
        }
    }    
}
 
// (F(n)) 실행 시간에 실행되며, Ω(1.6n)의 시간을 갖는다.
 
 
// 2. Tail-end Recursive 꼬리 재귀
// f(n - 1, fibo1 + fibo2, fibo1)로 재귀함수를 한 번만 실행
class MyFib2{
    long fib(long n) {
        return fibo_iter(n, 01);
    }
    
    long fibo_iter(long x, long a, long b) { // 5, 0, 1
        if (x==0return a;
        else return fibo_iter(x-1, b, a+b); // 4, 1, 1 // 3, 1, 2 //  2, 2, 3 // 1, 3, 5 // 0, 5, 8 => 5
    }            
}
 
// Θ(n) 실행 시간에 실행된다.
 
cs


1번 Binary Recursive에 경우 함수안의 자신의 함수를 2번 부른다.


받는 숫자 n이 커질수록 재귀 호출을 두 번 이상 부르므로 함수 호출 횟수가 방대하게 증가하는 문제가 발생하고, 


재귀 호출 깊이가 깊어지면 Stack을 많이 사용하는 문제가 발생한다.



2번 Tail Recursive에 경우 함수안의 자신의 함수를 1번 부른다.


Tail Recursion 를 쓰거나 반복 방식을 사용하면 Binary Recursive의 시간복잡도 및 Stack 사용을 줄일 수 있다.



마지막으로 소스를 첨부한다.


Pibonachi.java






스택을 이용한 n값을 받아 1부터 n까지의 합계 구하기 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package test1;
 
public class StackProblem {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MySum1 mysum1 = new MySum1();
        System.out.println(mysum1.sum(10000)); // StackOverFlow Error
        
        MySum2 mysum2 = new MySum2();
        System.out.println(mysum2.sum(10000));
        
    }
}
 
// 1부터 n까지의 재귀함수 호출의 합
class MySum1{
    int sum(int n) {
        if (n < 2)
            return n;
        return n + sum(n - 1);
    }    
}
 
// 1부터 n까지의 반복을 사용한 합 
class MySum2{
    int sumResult = 0;
    int sum(int n){
        while(n >= 0) {
            sumResult += n--;
        }        
        return sumResult;
    }    
}
cs


스택을 이용해 n값을 받으면 1부터 n값까지의 합계를 출력하는 소스이다.


예) n을 10으로 받으면 1부터 10까지 더해 값이 55가 나온다.



출력 값은 다음과 같다.







합계를 구하는 메소드는 총 2개(재귀함수 호출 function, 반복을 사용한 function) 로 나눠서 만들었다.



1. 1부터 n까지 재귀함수를 호출한 합



n값이 큰 상태에서 재귀함수를 호출해 합계를 하면 어느정도 숫자가 커지게 되었을 때 




다음과 같이 StackOverflowError가 발생하게 된다.


스택에 모두 담지 못하기 때문에 에러가 발생한 것이다.




2. 1부터 n까지 반복을 사용한 합



2번째 메소드는 에러를 발생시키지 않고 값이 나오는 것을 확인했다.


마지막으로 해당소스를 첨부한다.


StackProblem.zip




택배 배송조회 API인 스윗트래커(https://tracking.sweettracker.co.kr/)를 사용하여 배송정보를 받아오는 테스트를 해보겠다.



1. 먼저 https://tracking.sweettracker.co.kr/ 이동하여 회원가입을 한다.







2. 자신의 API 키를 발급받는다. 테스트이므로 무료키를 받겠다.









3. http://info.sweettracker.co.kr/apidoc API 문서를 본다.





4. 택배 배송정보를 RESTful 형태로 제공하므로 Base Url 에 자신이 필요로하는 api를 사용하면 된다.



5. 본인은 운송장 번호를 조회하기 위해 택배사목록을 조회하고 택배사목록과 운송장 번호를 통해 배송조회를 할 것이다.



6. 크롬 확장프로그램에서 POSTMAN을 설치 후 company-api와 tracking-api의 파람값을 알아본다.




company-api에서는 다음과 같이 코드와 택배회사명을 가져올 수 있고


tracking-api에서는 배송정보와 배송추적에 대한 정보를 가져올 수 있었다.




테스트를 위해 웹프로젝트를 생성하고 Jquery Ajax를 통해 해당 정보를 받아오겠다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<script>
$(document).ready(function(){
    var myKey = "JUI5lF7RHlbZHdNPCjhfYw"// sweet tracker에서 발급받은 자신의 키 넣는다.
    
        // 택배사 목록 조회 company-api
        $.ajax({
            type:"GET",
            dataType : "json",
            url:"http://info.sweettracker.co.kr/api/v1/companylist?t_key="+myKey,
            success:function(data){
                    
                    // 방법 1. JSON.parse 이용하기
                    var parseData = JSON.parse(JSON.stringify(data));
                     console.log(parseData.Company); // 그중 Json Array에 접근하기 위해 Array명 Company 입력
                    
                    // 방법 2. Json으로 가져온 데이터에 Array로 바로 접근하기
                    var CompanyArray = data.Company; // Json Array에 접근하기 위해 Array명 Company 입력
                    console.log(CompanyArray); 
                    
                    var myData="";
                    $.each(CompanyArray,function(key,value) {
                            myData += ('<option value='+value.Code+'>' +'key:'+key+', Code:'+value.Code+',Name:'+value.Name + '</option>');                        
                    });
                    $("#tekbeCompnayList").html(myData);
            }
        });
        // 배송정보와 배송추적 tracking-api
        $("#myButton1").click(function() {
            var t_code = $('#tekbeCompnayList option:selected').attr('value');
            var t_invoice = $('#invoiceNumberText').val();
            $.ajax({
                type:"GET",
                dataType : "json",
                url:"http://info.sweettracker.co.kr/api/v1/trackingInfo?t_key="+myKey+"&t_code="+t_code+"&t_invoice="+t_invoice,
                success:function(data){
                    console.log(data);
                    var myInvoiceData = "";
                    if(data.status == false){
                        myInvoiceData += ('<p>'+data.msg+'<p>');
                    }else{
                        myInvoiceData += ('<tr>');                
                        myInvoiceData += ('<th>'+"보내는사람"+'</td>');                     
                        myInvoiceData += ('<th>'+data.senderName+'</td>');                     
                        myInvoiceData += ('</tr>');     
                        myInvoiceData += ('<tr>');                
                        myInvoiceData += ('<th>'+"제품정보"+'</td>');                     
                        myInvoiceData += ('<th>'+data.itemName+'</td>');                     
                        myInvoiceData += ('</tr>');     
                        myInvoiceData += ('<tr>');                
                        myInvoiceData += ('<th>'+"송장번호"+'</td>');                     
                        myInvoiceData += ('<th>'+data.invoiceNo+'</td>');                     
                        myInvoiceData += ('</tr>');     
                        myInvoiceData += ('<tr>');                
                        myInvoiceData += ('<th>'+"송장번호"+'</td>');                     
                        myInvoiceData += ('<th>'+data.receiverAddr+'</td>');                     
                        myInvoiceData += ('</tr>');                                       
                    }
                    
                    
                    $("#myPtag").html(myInvoiceData)
                    
                    var trackingDetails = data.trackingDetails;
                    
                    
                    var myTracking="";
                    var header ="";
                    header += ('<tr>');                
                    header += ('<th>'+"시간"+'</th>');
                    header += ('<th>'+"장소"+'</th>');
                    header += ('<th>'+"유형"+'</th>');
                    header += ('<th>'+"전화번호"+'</th>');                     
                    header += ('</tr>');     
                    
                    $.each(trackingDetails,function(key,value) {
                        myTracking += ('<tr>');                
                        myTracking += ('<td>'+value.timeString+'</td>');
                        myTracking += ('<td>'+value.where+'</td>');
                        myTracking += ('<td>'+value.kind+'</td>');
                        myTracking += ('<td>'+value.telno+'</td>');                     
                        myTracking += ('</tr>');                                    
                    });
                    
                    $("#myPtag2").html(header+myTracking);
                    
                }
            });
        });
        
});
</script>
cs


AJAX를 통해 해당 정보를 잘 받아 출력되는 것을 확인하였다.





마지막으로 해당 전체소스를 첨부한다.


다운로드:


openAPI활용.zip






구글 로그인 api 웹 인증하기



웹 프로젝트를 간단히 생성한다.


나는 test1의 이름을 가진 프로젝트를 만들고 NewFile.html 파일을 만들었다.




그리고 html 파일의 내용은 구글 api에서 나온 소스를 모두 가져와서 사용했다.

참고 : (https://developers.google.com/identity/sign-in/web/





그리고 서버를 생성해 실행시켜본다.






google-signin-client_id가 맞지 않아 실행이 되지 않을 것이다.


client_id를 받기 위해 구글 개발자 콘솔로 가자.


1. https://console.developers.google.com 이동


2. 사용자 인증정보로 이동


3. 사용자 인증정보 만들기



4. 클라이언트ID가 생성됨을 확인할 수 있다.


5. OAuth 클라이언트 ID > 웹 어플리케이션 > 승인된 자바스크립트원본 http://localhost:8080 입력 

> 승인된 리디렉션 URI > http://localhost:8080/test1/NewFile.html 를 입력한다.


이 ID값을  NewFile.html 의 <meta name="google-signin-client_id" content="">

content값으로 넣어주고 실행한다.



이후 구글 로그인을 하게 되면 로그인한 이메일 주소와 이름, 사진, ID 토큰 값이 저장된다.




구글 로그인 api를 사용해 로그인이 잘 되는 것을 확인했다.







1. UNION, UNION ALL 차이점



1.1 UNION


1
2
3
4
5
6
7
8
9
-- UNION
SELECT 1 ID, '수학' SUBJECT, 90 SCORE FROM DUAL UNION
SELECT 1 ID, '수학' SUBJECT, 90 SCORE FROM DUAL UNION
SELECT 1 ID, '수학' SUBJECT, 90 SCORE FROM DUAL
 
-- Result 1
-- ID SUBJECT SCORE
-- 1     수학        90
;
cs


1.2 UNION ALL 



1
2
3
4
5
6
7
8
9
10
11
-- UNION ALL
SELECT 1 ID, '수학' SUBJECT, 90 SCORE FROM DUAL UNION ALL
SELECT 1 ID, '수학' SUBJECT, 90 SCORE FROM DUAL UNION ALL
SELECT 1 ID, '수학' SUBJECT, 90 SCORE FROM DUAL
 
-- Result 2
-- ID SUBJECT SCORE
-- 1     수학        90
-- 1     수학        90
-- 1     수학        90
;
cs


UNION 을 사용하면 컬럼의 값이 모두 같은 값이며 중복되면 중복되는 컬럼 row를 제외하고 출력되지만

UNION ALL 을 사용하면 컬럼의 값이 모두 같은 값이며 중복되더라도 모든 컬럼 row가 출력된다.




2. GROUP BY와 HAVING 이해하기



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-- GROUP BY와 HAVING 이해하기
 
SELECT A1.ID, A1.NAME, SUM(A1.SCORE) AS SCORE
  FROM (
            SELECT 1 ID, '김상현' NAME, '영어' SUBJECT, 80 SCORE FROM DUAL UNION ALL
            SELECT 1 ID, '김상현' NAME, '수학' SUBJECT, 80 SCORE FROM DUAL UNION ALL
            SELECT 2 ID, '이상현' NAME, '영어' SUBJECT, 100 SCORE FROM DUAL UNION ALL
            SELECT 2 ID, '이상현' NAME, '수학' SUBJECT, 100 SCORE FROM DUAL
           ) A1 
WHERE A1.NAME LIKE '%상현%'
GROUP BY A1.ID, A1.NAME, SCORE
HAVING SUM(SCORE) >= 170
 
-- RESULT 
 
-- ID NAME SCORE
-- 2  이상현   200
;
cs


해당 쿼리를 통해

GROUP BY는 데이터들을 그룹별로 나눌수 있고.

WHERE 절에서 집계함수를 사용 할 수 없으므로

HAVING을 사용하여 집계함수를 넣어 조건비교를 하고 있다.







1. 임시로 사용할 테이블 생성하기



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- 테이블 생성
 
CREATE TABLE MY_DUAL AS(
    SELECT 1 ID, 2000 SALARY FROM DUAL UNION ALL
    SELECT 2 ID, 2200 SALARY FROM DUAL UNION ALL
    SELECT 3 ID, 2400 SALARY FROM DUAL UNION ALL
    SELECT 4 ID, 2600 SALARY FROM DUAL UNION ALL
    SELECT 5 ID, 2800 SALARY FROM DUAL UNION ALL
    SELECT 6 ID, 2600 SALARY FROM DUAL UNION ALL
    SELECT 7 ID, 3000 SALARY FROM DUAL UNION ALL
    SELECT 8 ID, 2600 SALARY FROM DUAL
);
 
-- 기존 테이블 컬럼만 복사해 새 테이블 생성
 
CREATE TABLE COPY_NEW_TABLE AS(
    SELECT * FROM EXIST_TABLE_NAME
    WHERE 1=2 -- FALSE
);
cs



2. 컬럼 ADD, MODIFY, RENAME, DROP 사용하기 - 1


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
-- 1. 컬럼 ADD 
-- ALTER TABLE 테이블명 ADD 새 컬럼명 이름  데이터타입;
 
ALTER TABLE MY_DUAL ADD ANNUAL_INCOME VARCHAR2(1000);
UPDATE MY_DUAL SET ANNUAL_INCOME = SALARY;
 
-- 2. 컬럼 MODIFY 
-- ALTER TABLE 테이블 명 MODIFY 컬럼명 데이터타입;
 
ALTER TABLE MY_DUAL MODIFY SALARY VARCHAR2(1000);
 
-- 3. 컬럼 RENAME
-- ALTER TABLE 테이블명 RENAME COLUMN 기존컬럼명 TO 바꿀컬럼명;
 
ALTER TABLE MY_DUAL RENAME COLUMN ANNUAL_INCOME TO SALARY;
 
-- 4. 컬럼 DROP
-- ALTER TABLE 테이블명 DROP COLUMN 삭제할 컬럼명;
 
ALTER TABLE MY_DUAL DROP COLUMN SALARY;
cs



3. 컬럼에 데이터가 있을때 데이터 유형 바꾸는 방법 - 2



1
2
3
4
5
6
7
8
9
10
11
12
13
-- 컬럼에 데이터가 있을때 데이터 유형 바꾸는 방법
 
-- 1. 새 이름으로 새 컬럼을 하나 생성 (ADD)
ALTER TABLE MY_DUAL ADD ANNUAL_INCOME VARCHAR2(1000);
 
-- 2. 새 컬럼에 기존 데이터를 다시 입력 (SET)
UPDATE MY_DUAL SET ANNUAL_INCOME = SALARY;
 
-- 3. 기존 컬럼 삭제 (DROP)
ALTER TABLE MY_DUAL DROP COLUMN SALARY;
 
-- 4. 새 컬럼의 이름을 기존 컬럼 이름으로 바꿈 (RENAME)
ALTER TABLE MY_DUAL RENAME COLUMN ANNUAL_INCOME TO SALARY;
cs



현재 SALARY 컬럼의 데이터 유형은 NUMBER 

SALARY 컬럼은 데이터를 갖고 있다.

데이터를 가지고있는 컬럼에 대한 데이터유형 변경은 허용하지 않는다.


그러므로 새 이름의 필요한 데이터유형의 새로운 컬럼을 하나 생성한 뒤 

기존 컬럼이 가지고 있는 데이터를 새로운 데이터유형의 컬럼에 넣어주고(이동)

기존 컬럼을 삭제(DROP) 하고 새 이름의 새컬럼 이름을 기존 컬럼의 이름으로 바꿔주면 된다.






ORACLE 컬럼 중복값 제거(필터) 방법 정리



1. RANK() OVER, DENSE_RANK() OVER, ROW_NUMBER() OVER 함수




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- ORACLE 데이터의 중복 값을 제거(필터)하는 방법
-- RANK() OVER, DENSE_RANK() OVER, ROW_NUMBER() OVER 함수
 
SELECT ID
         , SALARY
         , RANK() OVER (ORDER BY SALARY DESC) RANK_FUNC -- 같은 값 공통 순위 1등이 3명 있다면 다음 순위는 2등이 아닌 4등이 된다.
         , DENSE_RANK() OVER (ORDER BY SALARY DESC) DENSE_RANK_FUNC -- 같은 값 공통 순위 1등이 3명 있다면 다음 순위는 2등이 된다.
         , ROW_NUMBER() OVER (ORDER BY SALARY DESC) ROW_NUMBER_FUNC -- 같은 값 공통 순위 1등이 3명 있다해도 순위가 각각 1,2,3등 매겨진다.
  FROM
         (
            SELECT 1 ID, 2000 SALARY FROM DUAL UNION ALL
            SELECT 2 ID, 2200 SALARY FROM DUAL UNION ALL
            SELECT 3 ID, 2400 SALARY FROM DUAL UNION ALL
            SELECT 4 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
            SELECT 5 ID, 2800 SALARY FROM DUAL UNION ALL
            SELECT 6 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
            SELECT 7 ID, 3000 SALARY FROM DUAL UNION ALL
            SELECT 8 ID, 2600 SALARY FROM DUAL -- 2600 중복
          );
cs


결과



2. ROW_NUMBER() OVER 사용한 SALARY 중복값 제거 - 1




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-- ROW_NUMBER() OVER 사용한 SALARY 중복값 제거 - 1
 
SELECT A1.*
  FROM (
            SELECT ID
                     , SALARY
                     , ROW_NUMBER() OVER (PARTITION BY SALARY ORDER BY ID)  AS RN
              FROM
                     (
                        SELECT 1 ID, 2000 SALARY FROM DUAL UNION ALL
                        SELECT 2 ID, 2200 SALARY FROM DUAL UNION ALL
                        SELECT 3 ID, 2400 SALARY FROM DUAL UNION ALL
                        SELECT 4 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
                        SELECT 5 ID, 2800 SALARY FROM DUAL UNION ALL
                        SELECT 6 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
                        SELECT 7 ID, 3000 SALARY FROM DUAL UNION ALL
                        SELECT 8 ID, 2600 SALARY FROM DUAL -- 2600 중복
                      )
           ) A1
WHERE A1.RN = 1
;
cs



결과




3. GROUP BY를 사용한 SALARY 중복값 제거 - 2



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-- GROUP BY를 사용한 SALARY 중복값 제거 - 2
 
SELECT MIN(ID)
         , SALARY
  FROM
         (
            SELECT 1 ID, 2000 SALARY FROM DUAL UNION ALL
            SELECT 2 ID, 2200 SALARY FROM DUAL UNION ALL
            SELECT 3 ID, 2400 SALARY FROM DUAL UNION ALL
            SELECT 4 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
            SELECT 5 ID, 2800 SALARY FROM DUAL UNION ALL
            SELECT 6 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
            SELECT 7 ID, 3000 SALARY FROM DUAL UNION ALL
            SELECT 8 ID, 2600 SALARY FROM DUAL -- 2600 중복
          )
GROUP BY SALARY
ORDER BY SALARY
;
cs



결과




4. DISTINCT 를 사용한 SALARY 중복값 제거 - 3




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- DISTINCT 를 사용한 SALARY 중복값 제거 - 3
 
SELECT DISTINCT A1.SALARY
  FROM
         (
            SELECT 1 ID, 2000 SALARY FROM DUAL UNION ALL
            SELECT 2 ID, 2200 SALARY FROM DUAL UNION ALL
            SELECT 3 ID, 2400 SALARY FROM DUAL UNION ALL
            SELECT 4 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
            SELECT 5 ID, 2800 SALARY FROM DUAL UNION ALL
            SELECT 6 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
            SELECT 7 ID, 3000 SALARY FROM DUAL UNION ALL
            SELECT 8 ID, 2600 SALARY FROM DUAL -- 2600 중복
          ) A1
;
cs



결과




5. ROWID 를 사용한 SALARY 중복값 제거 - 4



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-- ROWID를 이용한 SALARY 중복값 제거 - 4
 
-- 테이블 만들기 4-1
 
CREATE TABLE MY_DUAL AS(
    SELECT 1 ID, 2000 SALARY FROM DUAL UNION ALL
    SELECT 2 ID, 2200 SALARY FROM DUAL UNION ALL
    SELECT 3 ID, 2400 SALARY FROM DUAL UNION ALL
    SELECT 4 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
    SELECT 5 ID, 2800 SALARY FROM DUAL UNION ALL
    SELECT 6 ID, 2600 SALARY FROM DUAL UNION ALL -- 2600 중복
    SELECT 7 ID, 3000 SALARY FROM DUAL UNION ALL
    SELECT 8 ID, 2600 SALARY FROM DUAL -- 2600 중복
)
;
 
-- 테이블에서 ROWID 이용 중복값 제거 4-2
 
SELECT ID, SALARY
  FROM MY_DUAL
WHERE ROWID IN (SELECT MIN(ROWID)
                              FROM MY_DUAL
                            GROUP BY SALARY)
;
cs



결과




ORACLE의 여러 함수를 사용해 컬럼의 중복되는 값 을 제거 할 수 있는 것을 확인했다.




라즈베리파이 원격접속 방법


  • ssh를 사용가능하게 하여 putty로 연결해 원격접속 하는방법


  • xrdp를 설치해 원격데스크톱 연결로 접속하는 방법




1. putty로 ssh 접속하기 위해서 ssh를 사용하게 설정해줘야 한다.




2. putty 다운로드 및 접속





login id : pi / password : raspberry 로 접속가능하다.




sudo apt-get install xrdp 입력 설치 후 


ifconfig 입력




ip 192.168.0.12 확인 후


원격 데스크톱 연결로 들어가 ip를 입력하고 접속하면





xrdp 로그인 창이 뜨게 되고 username과 password(초기비밀번호: raspberry) 를 입력하면




실제 라즈베리파이 OS화면이 나타나게 된다.





'전체 > 라즈베리파이' 카테고리의 다른 글

라즈베리파이 준비 및 환경설정  (0) 2017.10.17

+ Recent posts