상세 컨텐츠

본문 제목

프로그래머 도전기 47일차

프로그래머가 될거야!

by Choyee 2023. 10. 17. 00:33

본문

오늘은

오늘은 월요일입니다

새로운 한 주가 시작되었습니다

 

 

 

학원 수업

<<조인>>
1. Oracle DBMS 방식 - oracle, mysql
- 동등 조인(EQUI JOIN)
=> SELECT *
     FROM a, b 테이블
     WHERE절 a.c칼럼 = b.c칼럼

2. 표준 방식 - 모든 DBMS
- 내부조인(INNER JOIN)
=> SELECT *
     FROM a 테이블(INNER) JOIN b 테이블
     ON a,c칼럼 = b,c칼럼

-- 조인 : 두 테이블을 연결하여 사용하는 기법 

-- 동등조인(EQUI) : 조인 조건이 정확히 일치하는 경우에 결과 출력
-- 외부조인(OUTER) : 조인 조건이 정확히 일치하지 않아도 모든 결과를 출력

SELECT * FROM book;
SELECT * FROM customer;
SELECT * FROM orders;

-- 카테시안곱 : customer(6) * orders(10) = 60
SELECT cus.name, ord.saleprice
FROM customer cus, orders ord; -- or조건

-- 고객(customer)과 고객의 주문(oreders)에 관한 데이터를 모두 검색하시오
-- 고객이름으로 정렬(자동으로 그룹화 됨)
SELECT cus.name, ord.saleprice
FROM customer cus, orders ord
WHERE cus.custid = ord.custid   -- 동등조인 and조건
ORDER BY cus.name;

-- 고객(customer)과 고객의 주문(oreders)에 관한 데이터를 모두 검색하시오
-- 조건 => '박지성' 고객의 주문내역을 검색하시오
SELECT cus.name, ord.saleprice
FROM customer cus, orders ord
WHERE cus.custid = ord.custid
   AND cus.name = '박지성'
ORDER BY ord.saleprice;

-- 고객(customer)과 고객의 주문(oreders)에 관한 데이터를 모두 검색하시오
-- 고객별 주문 금액의 총액 출력(GROUP BY 결과)
-- 김연아 고객의 주문 총금액을 출력(HAVING으로 제한을 둠)
SELECT cus.custid, cus.name, SUM(ord.saleprice)
FROM customer cus, orders ord
WHERE cus.custid = ord.custid
   -- AND cus.name = '김연아'
GROUP BY cus.custid, cus.name   -- SELECT와 GROUP BY 동기화 필요
   HAVING cus.name = '김연아'
ORDER BY cus.name;

-- 주문하지 않은 데이터도 모두 검색
-- 조건이 일치하지 않은 테이블에 +를 넣어줌
SELECT cus.name, ord.saleprice
FROM customer cus, orders ord
WHERE cus.custid = ord.custid(+)   -- 외부조인  => orders쪽에서 주문하지 않은 고객까지 출력
ORDER BY cus.name;

-- 고객의 이름, 주문한 도서 이름, 주문일, 주문금액
SELECT cus.name, bk.bookname, ord.orderdate, ord.saleprice
FROM customer cus, book bk, orders ord
WHERE cus.custid = ord.custid    -- 기본키 = 외래키
   AND bk.bookid = ord.bookid
ORDER BY cus.name;

-- 표준 조인(ANSI SQL)

-- 내부 조인(INNER JOIN)
-- 고객(customer)과 고객의 주문(oreders)에 관한 데이터중 
-- 고객의 이름과 고객이 주문한 도서의 판매가격을 검색하시오
SELECT cus.name, ord.saleprice
FROM customer cus INNER JOIN orders ord  -- INNER 생략 가능
    ON cus.custid = ord.custid   -- 동등조인
ORDER BY cus.name;

-- 외부 조인(OUTER JOIN)
-- 고객(customer)과 고객의 주문(oreders)에 관한 데이터중 
-- 주문되지 않은 데이터를 포함하여 고객의 이름과 고객이 주문한 도서의 판매가격 검색
SELECT cus.name, ord.saleprice
FROM customer cus LEFT OUTER JOIN orders ord  -- 테이블 기준에 따라 LEFT, RIGHT가 달라진다
    ON cus.custid = ord.custid(+)   -- 외부조인  => orders쪽에서 주문하지 않은 고객까지 출력
ORDER BY cus.name;

COMMIT;


<<상품, 상품리뷰, 이벤트>>
<상품엔티티 - 상품코드, 상품명, 가격>
=> product(테이블) - product_code, product_name, price(칼럼) 



<상품후기(리뷰)엔티티 - 리뷰번호(자동순번), 상품코드(외래키), 회원아이디,
                      리뷰내용, 작성일>
=> product_review - review_no, product_code, member_id, content, regdate

-- product_review 테이블 생성
-- CLOB(Character Large of Object) = 매우 큰 문자열 자료형(4GB)
CREATE TABLE  product_review(
    review_no        NUMBER PRIMARY KEY,                       -- 리뷰번호
    product_code   CHAR(6) NOT NULL,          -- 상품코드
    member_id       VARCHAR2(20) NOT NULL, -- 회원아이디
    content           CLOB NOT NULL,             -- 리뷰내용
    regdate           DATE DEFAULT SYSDATE,   -- 작성일 => 자동으로 들어감
    FOREIGN KEY(product_code) REFERENCES product(product_code)  -- 외래키
);

-- 자동순번(nocache = 초기화하면 1부터 시작) 
CREATE SEQUENCE seq_rno NOCACHE;

DROP SEQUENCE seq_rno;

INSERT INTO product_review(review_no, product_code, member_id, content)
VALUES (seq_rno.NEXTVAL, '100001', 'today10', '무소음인데 소음이 조금 있는 듯...');
INSERT INTO product_review(review_no, product_code, member_id, content)
VALUES (seq_rno.NEXTVAL, '100001', 'cloud100', '무선이라 정말 편하네요!');
INSERT INTO product_review(review_no, product_code, member_id, content)
VALUES (seq_rno.NEXTVAL, '100002', 'sky123', '게임할 맛 납니다');

SELECT * FROM product_review;

--테이블 유지, 데이터 전체 삭제
TRUNCATE TABLE product_review;

-- 상품코드가 '100001'이고, 회원아이디가 cloud100'인 상품의 정보를 출력하시오
SELECT * FROM product_review
WHERE product_code = '100001' 
   AND member_id = 'cloud100';

-- 상품 아이템 = 3개, 리뷰 있는 아이템 = 2개
-- 리뷰가 있는 상품을 검색하시오
-- 조건일치 : a테이블의 기본키 = b테이블의 외래키
SELECT * FROM product a, product_review b
WHERE a.product_code = b.product_code;

SELECT * FROM product a INNER JOIN product_review b
     ON a.product_code = b.product_code;
     
SELECT b.product_code,
          b.product_name,
          b.price,
          a.member_id,
          a.content,
          a.regdate
FROM product_review a RIGHT JOIN product b
   ON a.product_code = b.product_code;

-- 리뷰의 유무에 관계없이 상품의 정보를 검색하시오
-- 동등조인 방식(product의 상품은 모두 출력되고, 리뷰는 있든 없든 관계없음)
-- review가 없으면 null로 출력된다
SELECT * FROM product a, product_review b
WHERE a.product_code = b.product_code(+);

-- 표준방식(외부조인 - OUTER JOIN)
-- OUTER 생략 가능
SELECT * FROM product a LEFT OUTER JOIN product_review b
     ON a.product_code = b.product_code;

COMMIT;


<이벤트엔티티 - 이벤트 번호, 이벤트 이름, 이벤트 시작일, 이베트 종료일>
=> event- event_no, event_name, start_date, end_date

-- event 테이블 만들기
CREATE TABLE event (
    event_no       NUMBER PRIMARY KEY,        -- 이벤트 번호
    event_name    VARCHAR2(50) NOT NULL,    -- 이벤트 이름
    start_date      VARCHAR2(20) NOT NULL,    -- 이벤트 시작일
    end_date       VARCHAR2(20) NOT NULL     -- 이벤트 종료일
);

-- 자동 일련번호
CREATE SEQUENCE  seq_eno NOCACHE;

INSERT INTO event(event_no, event_name, start_date, end_date)
VALUES (seq_eno.NEXTVAL, '20% 할인 쿠폰 증정', '2023-10-10', '2023-10-20');
INSERT INTO event(event_no, event_name, start_date, end_date)
VALUES (seq_eno.NEXTVAL, '마우스 패드 증정', '2023-11-15', '2023-11-25');
INSERT INTO event(event_no, event_name, start_date, end_date)
VALUES (seq_eno.NEXTVAL, '20% 할인 쿠폰 증정', '2023-12-10', '2023-12-20');

DROP TABLE evnet;

SELECT * FROM event;

-- 이벤트 기간 동안에 리뷰를 작성한 고객
-- 리뷰테이블과 이벤트 테이블 조인
-- 일대다(이벤트와 리뷰)
-- 비동등조인(>=, <=, BETWEEN AND)
SELECT e.event_name,
         r.member_id,
         r.content,
         r.regdate
FROM event e, product_review r
WHERE r.regdate BETWEEN e.start_date AND e.end_date; 

-- 내부조인(INNER JOIN ON)
SELECT e.event_name,
         r.member_id,
         r.content,
         r.regdate
FROM event e INNER JOIN product_review r
   ON r.regdate
        >= e.start_date AND r.regdate <= e.end_date;
   -- = BETWEEN e.start_date AND e.end_date; 
 
COMMIT;



* 테이블 삭제(DDL) : ROLLBACK 불가
1. DROP TABLE 테이블명 = 테이블 자체를 삭제, 데이터는 당연히 삭제
2. TRUNCATE TABLE 테이블명 = 데이터만 삭제, 테이블 유지

* 데이터 삭제 : ROLLBACK가능
1. DELETE FROM 테이블명 = 데이터 전체 삭제
2. DELETE FROM 테이블명 WHERE 칼러명 = 데이터 1개 삭제

 

 

 

CSS 공부

<<CSS 선택자>>
= 쓰기에 있어서 필수적인 부분
CSS의 기본 규칙 = selector{ property: value; } 여기에서의 selector가 선택자이다

<전체 선택자>
문서의 모든 요소를 다 선택할 수 있다

* {
  color: black;
}



<요소 선택자>
= 지정된 타입의 모든 항목을 선택
   이미지나, 버튼 등

button {
   font-size: 30px;
}



<쉼표를 이용한 선택자 합치기>
= 여러개의 선택자가 나올 때 쉼표를 사용하면 된다
   비슷한 스타일을 적용하고 싶은 두 개의 요소나
   그 이상의 요소들이 있을 경우에 아주 흔히 쓰인다

h1, h2 {
    color: magenta;
}



<ID 선택자>
=> <input>에 ID속성을 쓰고 <label>을 입력한 다음 id를 label에 맞게 해주면
     <label>이 <input>과 연결된다
=> ID는 CSS의 모든 요소에 훅을 제공한다 
     = CSS가 하나의 요소를 뽑아내도록 한다
= HTML에 추가되는 속성으로 한 부분의 스타일을 바꿔주는 역할을 한다
=> ID는 띄어쓰기가 없어야 하고
     되도록 짧으면서 의미가 담겨 있어야 한다
=> 마크업에 ID를 추가하고 ID이름으로 연결하고
     ID 앞에는 꼭 해시표시(우물정자)를 붙여야 하고
     빈 곳은 없어야 한다

* ID는 하나의 ID 페이지 내에 한 번만 나와야 한다
   = ID는 중복되면 안된다, 고유한 식별자여야 한다
  => ID는 최소화 하는 것이 좋다

#logout {
     color: orange;
     height 200px;
}



<클래스 선택자>
= 요소 선택자와 함께 가장 많이 쓰이는 선택자
=> 클래스 = ID와 비슷한 개념
                 마크업에 뭔가를 추가해서 훅을 걸어 CSS로 연결
                 ID와는 다르게 클래스는 여러 요소에 적용된다
              => 요소를 묶어 주기 떄문에 몇 개의 그룹을 만들어
                   비슷한 스타일을 적용할 수 있다

.complete {
     color: green;
}
// 마침표에 클래스 이름이 있는 선택자 구문 사용 가능
// ID선택자와 비슷해 보이지만 해시 표시 대신 마침표가 들어가 있다

 

=> 클래스를 써서 요소들을 그룹으로 묶을 때는
     그 요소들의 유형이 같지 않아도 된다
     = 나중에 찾고 싶은 어떤 요소에든 붙일 수 있다

 

 

<자손 선택자>
= 띄어쓰기를 이용한다

li a {
   color: teal;
}
// li 뒤에 한칸 띄우고 a가 있을 경우
// <li>태그에 중첩된 모든 자손 요소를 선택하라는 뜻

=> <li> 태그에 연결된 걸 선택하게 한다
=> 이 공백이 중요하며 쉼표와는 다르다
     쉼표의 경우 = <li>태그와 앵커 태그를 선택
     띄어쓰기 = <li> 태그 안의 앵커 태그를 선택 => <li>태그는 선택하지 않는다
=> 각각에 클래스를 부여해서 마침표를 이용한 클래스 선택자와
     띄어쓰기를 쓰는 자손 선택자를 조합해서 쓰면
     클래스에 속한 앵커 태그가 선택되게 된다
= <li>, <footer> 외에도 어디에든 쓸 수 있다

* 클래스 선택자와 함께 자주 쓰이는 선택자
  마침표를 쓰고 띄어쓰기를 한다
  스타일을 부여하고 싶은 것마다 일일이 클래스를 쓰지 않아도 되므로 자주 이용되는 방법
  포스트로 지정하고 포스트에 속한 앵커 태그나 버튼을 선택하게 할 경우
  각자에 클래스를 따로 부여하지 않아도 된다
  어떠한 경우에는 사우이 항목에 클래스를 부여해서 사용하면 된다

 

 


<인접 선택자>
= 결합자 라고 불리기도 한다

h1 + p {
   color: red;
}
// h1, p = 요소 선택자
// + = 전체 선택의 명령을 바꾸는 결합자

=> 이 + 부호가 인접 선택자이다
     = <h1>태그 바로 다음에 오는 <p>태그를 모두 선택하게 한다
     => 즉 <h1> 태그 다음에 오면서 같은 단계에 있는 <p>태그를 선택한다
          = 부모 자식이 아닌 형제 관계의 개념

 

 


<직계 선택자>
= 부등호 > 를 사용한다

div > li {
   color: white;
}
// 이 경우 > 는 <div>태그에 속한 모든 <li>태그가 아니라
// 직계 자손인 <li>태그만 선택한다
//  = 한 단계 아래만 선택한다는 뜻

=> 직계 자손인 태그만 선택한다

 

 


<속성 선택자>
= 특정 속성을 가진 요소를 선택할 수 있다
   주로 <input>요소와 함께 쓰이는데 그 중 한<type>을 선택하려는 경우
   해당 type의 모든 input을 선택할 때는 속성 선택자를 사용한다

input[type="text"] {
   width: 300px;
   color: yellow;
}
// 대괄호를 입력하고 그 안에
// '속성 이름 ="" 을 입력하는 것


*= 로 조금 더 어렴풋한 일치를 찾을 수도 있다

a[href*="example"] {
   font-size: 2em;
}
// href속성에 example이 포함된 모든 앵커 태그 라는 뜻

 

 

CSS

/* *{
    background-color: cyan;
}*/

body{
    background-color: #f1faee;
}

button {
    font-size: 30px;
    background-color: #a8dadc;
}

h1,h2 {
    color: #1d3557;
}

#signup{
    background-color: #1d3557;
    color: #f1faee;
}

span {
    color: #457b9d;
}

.tag {
    background-color: #e63946;
    color: #f1faee;
    font-size: small;
}

.post a {
    color: #457b9d;
}

footer a {
    color: #e63946
}

h2 + button {
    font-size: 20px;
}

input[type="password"] {
    color: yellowgreen;
}

section[class="post"] {
    background-color: palegreen;
}

a[href*="google"] {
    color:magenta;
}

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS Selectors</title>
    <link rel="stylesheet" href="app2.css">
</head>
<body>
    <nav>
        <label for="search">Sezrch</label>
        <input type="text" placeholder="search" id="search">
        <input type="password" placeholder="password">
        <button>Log In</button>
        <button id="signup">Sign Up</button>
    </nav>
    <main>
        <h1>Popular Posts</h1>
        <section class="post">
            <span>Posted by<a href="#213adas">/u/not_funny</a></span>
            <h2>Lol look at this hilarious meme <span class="tag">funny</span></h2>
            <button>+Vote</button>
            <hr>
        </section>
        <section class="post">
            <span>Posted by<a href="#345adas">/u/gooner4lyfe</a></span>
            <h2>Hapy birthdat to the strongest defender/bodyuard in the prem! <span class="tag">gunners</span></h2>
            <button>+Vote</button>
            <hr>
        </section>
        <section class="post">
            <span>Posted by<a href="#981adas">/u/dogfan</a></span>
            <h2>This Corgi got some good stuff from th vet. <span class="tag">dogs</span></h2>
            <button>+Vote</button>
            <hr>
        </section>
    </main>
    <footer>
        <nav>
            <ul>
                <li>
                    <a href="#home">Home</a>
                </li>
                <li>
                    <a href="#about">About</a>
                </li>
                <li>
                    <a href="#contact">Contact</a>
                </li>
                <li>
                    <a href="www.google.com">Google</a>
                </li>
            </ul>
        </nav>
        <a href="#license">Content is available under these licenses.</a>

    </footer>
    
</body>
</html>

 

브라우저 페이지

 

 

 

Coding Test Practice
Description
Suppose that a string s consisting of both lower-case and upper-case letters are given. Write a function "solution" to return True when the number of 'p' and 'y' in s are the same, and return False otherwise. Note that when there is neither 'p' nor 'y', it should always return True. Also, when comparing the number of 'p' and 'y', lower-case and upper-case are not distinguished. For example, if s is "pPoooyY", then return true. In the case of "Pyy", return false.
function solution(s){
    var countP = 0;
    var countY =0;
    s = s.toLowerCase();
    
    for(var i = 0; i < s.length; i++){
        if(s[i] == "p"){
            countP++;
        }
        if(s[i] == "y"){
            countY++;
        }
    }
    // [실행] 버튼을 누르면 출력 값을 볼 수 있습니다.
    console.log('Hello Javascript')

    return countP == countY ? true : false;
}

문제가 왜 영어로 나오는지는 모르겠지만 어찌됐든...
if조건문을 활용하여 해결할 수 있었던 문제

 

 

Description
임의의 양의 정수 n에 대해, n이 어떤 양의 정수 x의 제곱인지 아닌지 판단하려 합니다. n이 양의 정수 x의 제곱이라면 x+1의 제곱을 리턴하고, n이 양의 정수 x의 제곱이 아니라면 -1을 리턴하는 함수를 완성하세요.
function solution(n) {
    for(var i = 1; i <= n; i++){
        if(i*i == n){
            return (i+1) * (i+1);
        }
    }  
    return -1;
}

 

 

 

Description
함수 solution은 정수 n을 매개변수로 입력받습니다. n의 각 자릿수를 큰것부터 작은 순으로 정렬한 새로운 정수를 리턴해주세요. 예를들어 n이 118372면 873211을 리턴하면 됩니다.
function solution(n) {
    var answer = 0;
    var nStr = n.toString().split('').map(Number);
    nStr.sort((a, b) => b - a);

    return parseInt(nStr.join(''));
}

정수n을 문자열로 변환 -> 문자열을 각 문자로 나눔 => 각 자릿수가 개별 문자열 요소로 포함된 배열 생성
map(Number) 함수 -> 배열의 각 문자열 요소를 숫자로 변환
sort()메서드를 사용 -> 비교함수 이용 -> 큰 순서로 정렬 
정렬된 배열을 다시 문자열로 결합 -> parseInt()함수 사용 => 문자열을 정수로 변환
(* 메서드 = 객체 내에서 정의. 객체에 메서드를 추가할 때 해당 객체의 속성으로 함수를 할당)
(* 함수 = 독립적으로 정의. 전역 스코프나 다른 함수 내부에서 정의될 수 있다)

 

 

Description
양의 정수 x가 하샤드 수이려면 x의 자릿수의 합으로 x가 나누어져야 합니다. 예를 들어 18의 자릿수 합은 1+8=9이고, 18은 9로 나누어 떨어지므로 18은 하샤드 수입니다. 자연수 x를 입력받아 x가 하샤드 수인지 아닌지 검사하는 함수, solution을 완성해주세요.
function solution(x) {
    var xStr = x.toString();
    var sum = 0;
        for(var i = 0; i < xStr.length; i++){
            sum += parseInt(xStr[i]);
        }
    return x % sum == 0 ? true : false;
}

 

 

 

Description
두 정수 a, b가 주어졌을 때 a와 b 사이에 속한 모든 정수의 합을 리턴하는 함수, solution을 완성하세요. 예를 들어 a = 3, b = 5인 경우, 3 + 4 + 5 = 12이므로 12를 리턴합니다.
function solution(a, b) {
    var answer = 0;
    if(a <= b){
        for(var i = a; i <= b; i++){
            answer += i;
        }
    }else {
        for(var i = b; i <= a; i++){
        answer += i;
        }
    }
    return answer;
}

 

 

 

 

 

2023. 10. 16 (월)

관련글 더보기