Coding History

국비 지원 IT(웹앱개발) 취업반 강의 25일차 (JDBC, DB)

BlackBirdIT 2024. 7. 10. 20:08

차가 너무 막혀서 강의실에 오기까지 1시간 반이 걸렸다. 거의 도착할 때 쯤 보니까 신호등이 고장나서 경찰분들이 수신호로 차를 보내고 계시더라. 아마 비 때문에 낙뢰라도 맞아서 그런게 아닌가 싶다. 아무튼 지각은 고사하고 도착하자마자, 어제 내가 구현해 놓은 것들 + detail 기능까지 구현하라고 하셨다. 어제 나머지는 다 해놔서 detail만 하면 됐는데 검증할 수 있는 코드도 만들었고 list기능을 구현해 놓은 곳에서 데이터를 뽑아오는 코드도 있어서 되게 빨리 다 했다.

else if (cmd.startsWith("article detail")) {
            int id = 0;
            try {
                id = Integer.parseInt(cmd.split(" ")[2]);
            } catch (Exception e) {
                System.out.println("번호는 정수로 입력해");
                return 0;
            }
            SecSql sql = new SecSql();
            sql.append("SELECT COUNT(*) FROM article WHERE id = ?;", id);
            int articleId = DBUtil.selectRowIntValue(conn, sql);
            if (articleId == 0) {
                System.out.println(id + "번 게시물 없어.");
            } else {
                List<Article> articles = new ArrayList<>();

                SecSql sql2 = new SecSql();
                sql2.append("SELECT * FROM article WHERE id = ?;", id);
                List<Map<String, Object>> articleListMap = DBUtil.selectRows(conn, sql2);
                for (Map<String, Object> articleMap : articleListMap) {
                    articles.add(new Article(articleMap));
                }
                if (articles.size() == 0) {
                    System.out.println(id + "번 게시물 없어");
                } else {
                    for (Article article : articles) {
                        System.out.println("번호 : " + article.getId());
                        System.out.println("제목 : " + article.getTitle());
                        System.out.println("내용 : " + article.getBody());
                        System.out.println("작성시간 : " + article.getRegDate());
                        System.out.println("수정시간 : " + article.getUpdateDate());

                    }
                }

            }
        }

그리고 강사님이 써주시는 코드에서 약간의 디테일을 손을 봤다. modify 부분인데 title과 body에 아무것도 쓰지 않을 경우도 대비해서 if문을 추가 했다.

System.out.println("==수정==");
System.out.print("새 제목 : ");
String title = sc.nextLine().trim();
System.out.print("새 내용 : ");
String body = sc.nextLine().trim();
SecSql sql2 = new SecSql();
sql2.append("UPDATE article");
sql2.append("SET updateDate = NOW(),");
if(!title.isEmpty()) {
    sql2.append("title = ?,", title);
}
if(!body.isEmpty()) {
    sql2.append("`body`= ?", body);
}
sql2.append("WHERE id = ?;", id);

DBUtil.update(conn, sql2);
System.out.println(id + "번 글이 수정되었습니다.");

article detail 강사님은 이렇게 해결하셨다.

                SecSql sql2 = new SecSql();
                sql2.append("SELECT * FROM article WHERE id = ?;", id);
                Map<String, Object> articleListMap = DBUtil.selectRow(conn, sql2);

                if (articleListMap.isEmpty()) {
                    System.out.println(id + "번 게시물 없어");
                    return 0;
                }

                Article article = new Article(articleListMap);


                System.out.println("번호 : " + article.getId());
                System.out.println("제목 : " + article.getTitle());
                System.out.println("내용 : " + article.getBody());
                System.out.println("작성시간 : " + article.getRegDate());
                System.out.println("수정시간 : " + article.getUpdateDate());
            }
        }

나 처럼 검증하기 위해서 쿼리를 하나 더 쓰지 않고 쿼리 하나를 쓰고 그 곳이 비어있을 때 리턴 시키는 방식을 사용하셨다.

delete도 비슷했다. 작성하시고서 delete의 위험성에 대해서 말씀하셨다. 예를 들어보자면 고객의 데이터를 확인도 하지 않고 지우는 경우? 같은 것을 말씀하시면서 주의를 요했다. 우리는 지금 연습중이니까 일단은 신경쓰지 마시라고 하셨다.

아무튼 코드 전문을 비교해보면

  • 강사님 코드
    package org.koreait;
    

import org.koreait.Util.DBUtil;
import org.koreait.Util.SecSql;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class App {

public void run() {
    System.out.println("==프로그램 시작==");
    Scanner sc = new Scanner(System.in);

    while (true) {
        System.out.print("명령어 > ");
        String cmd = sc.nextLine().trim();

        Connection conn = null;

        try {
            Class.forName("org.mariadb.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        String url = "jdbc:mariadb://127.0.0.1:3306/AM_JDBC_2024_07?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul";

        try {
            conn = DriverManager.getConnection(url, "root", "");

            int actionResult = doAction(conn, sc, cmd);

            if (actionResult == -1) {
                System.out.println("==프로그램 종료==");
                sc.close();
                break;
            }

        } catch (SQLException e) {
            System.out.println("에러 1 : " + e);
        } finally {
            try {
                if (conn != null && !conn.isClosed()) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

private int doAction(Connection conn, Scanner sc, String cmd) {

    if (cmd.equals("exit")) {
        return -1;
    }

    if (cmd.equals("article write")) {
        System.out.println("==글쓰기==");
        System.out.print("제목 : ");
        String title = sc.nextLine();
        System.out.print("내용 : ");
        String body = sc.nextLine();

        SecSql sql = new SecSql();

        sql.append("INSERT INTO article");
        sql.append("SET regDate = NOW(),");
        sql.append("updateDate = NOW(),");
        sql.append("title = ?,", title);
        sql.append("`body`= ?;", body);

        int id = DBUtil.insert(conn, sql);

        System.out.println(id + "번 글이 생성되었습니다");


    } else if (cmd.equals("article list")) {
        System.out.println("==목록==");

        List<Article> articles = new ArrayList<>();

        SecSql sql = new SecSql();
        sql.append("SELECT *");
        sql.append("FROM article");
        sql.append("ORDER BY id DESC");

        List<Map<String, Object>> articleListMap = DBUtil.selectRows(conn, sql);

        for (Map<String, Object> articleMap : articleListMap) {
            articles.add(new Article(articleMap));
        }


        if (articles.size() == 0) {
            System.out.println("게시글이 없습니다");
            return 0;
        }

        System.out.println("  번호  /   제목  ");
        for (Article article : articles) {
            System.out.printf("  %d     /   %s   \n", article.getId(), article.getTitle());
        }
    } else if (cmd.startsWith("article modify")) {

        int id = 0;

        try {
            id = Integer.parseInt(cmd.split(" ")[2]);
        } catch (Exception e) {
            System.out.println("번호는 정수로 입력해");
            return 0;
        }

        SecSql sql = new SecSql();
        sql.append("SELECT *");
        sql.append("FROM article");
        sql.append("WHERE id = ?", id);

        Map<String, Object> articleMap = DBUtil.selectRow(conn, sql);

        if (articleMap.isEmpty()) {
            System.out.println(id + "번 글은 없어");
            return 0;
        }

        System.out.println("==수정==");
        System.out.print("새 제목 : ");
        String title = sc.nextLine().trim();
        System.out.print("새 내용 : ");
        String body = sc.nextLine().trim();

        sql = new SecSql();
        sql.append("UPDATE article");
        sql.append("SET updateDate = NOW()");
        if (title.length() > 0) {
            sql.append(",title = ?", title);
        }
        if (body.length() > 0) {
            sql.append(",`body` = ?", body);
        }
        sql.append("WHERE id = ?", id);

        DBUtil.update(conn, sql);

        System.out.println(id + "번 글이 수정되었습니다.");
    } else if (cmd.startsWith("article detail")) {

        int id = 0;

        try {
            id = Integer.parseInt(cmd.split(" ")[2]);
        } catch (Exception e) {
            System.out.println("번호는 정수로 입력해");
            return 0;
        }

        System.out.println("==상세보기==");

        SecSql sql = new SecSql();
        sql.append("SELECT *");
        sql.append("FROM article");
        sql.append("WHERE id = ?", id);

        Map<String, Object> articleMap = DBUtil.selectRow(conn, sql);

        if (articleMap.isEmpty()) {
            System.out.println(id + "번 글은 없어");
            return 0;
        }

        Article article = new Article(articleMap);

        System.out.println("번호 : " + article.getId());
        System.out.println("작성날짜 : " + article.getRegDate());
        System.out.println("수정날짜 : " + article.getUpdateDate());
        System.out.println("제목 : " + article.getTitle());
        System.out.println("내용 : " + article.getBody());
    } else if (cmd.startsWith("article delete")) {

        int id = 0;

        try {
            id = Integer.parseInt(cmd.split(" ")[2]);
        } catch (Exception e) {
            System.out.println("번호는 정수로 입력해");
            return 0;
        }

        SecSql sql = new SecSql();
        sql.append("SELECT *");
        sql.append("FROM article");
        sql.append("WHERE id = ?", id);

        Map<String, Object> articleMap = DBUtil.selectRow(conn, sql);

        if (articleMap.isEmpty()) {
            System.out.println(id + "번 글은 없어");
            return 0;
        }

        System.out.println("==삭제==");

        sql = new SecSql();
        sql.append("DELETE FROM article");
        sql.append("WHERE id = ?", id);

        DBUtil.delete(conn, sql);

        System.out.println(id + "번 글이 삭제되었습니다.");
    }
    return 0;
}

}


- 내 코드
```java
package org.koreait;

import org.koreait.Util.DBUtil;
import org.koreait.Util.SecSql;

import java.sql.*;
import java.util.*;

public class App {

    public void run() {
        System.out.println("==프로그램 시작==");
        Scanner sc = new Scanner(System.in);

        while (true) {
            System.out.print("명령어 > ");
            String cmd = sc.nextLine().trim();

            Connection conn = null;

            try {
                Class.forName("org.mariadb.jdbc.Driver");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

            String url = "jdbc:mariadb://127.0.0.1:3306/AM_JDBC_2024_07?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul";

            try {
                conn = DriverManager.getConnection(url, "root", "1234");

                int actionResult = doAction(conn, sc, cmd);

                if (actionResult == -1) {
                    System.out.println("==프로그램 종료==");
                    sc.close();
                    break;
                }

            } catch (SQLException e) {
                System.out.println("에러 1 : " + e);
            } finally {
                try {
                    if (conn != null && !conn.isClosed()) {
                        conn.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private int doAction(Connection conn, Scanner sc, String cmd) {

        if (cmd.equals("exit")) {
            return -1;
        }

        if (cmd.equals("article write")) {
            System.out.println("==글쓰기==");
            System.out.print("제목 : ");
            String title = sc.nextLine();
            System.out.print("내용 : ");
            String body = sc.nextLine();

            SecSql sql = new SecSql();

            sql.append("INSERT INTO article");
            sql.append("SET regDate = NOW(),");
            sql.append("updateDate = NOW(),");
            sql.append("title = ?,", title);
            sql.append("`body`= ?;", body);

            int id = DBUtil.insert(conn, sql);

            System.out.println(id + "번 글이 생성되었습니다");

        } else if (cmd.equals("article list")) {
            System.out.println("==목록==");


            List<Article> articles = new ArrayList<>();

            SecSql sql = new SecSql();
            sql.append("SELECT *");
            sql.append("FROM article");
            sql.append("ORDER BY id DESC");

            List<Map<String, Object>> articleListMap = DBUtil.selectRows(conn, sql);

            for (Map<String, Object> articleMap : articleListMap) {
                articles.add(new Article(articleMap));
            }

            if (articles.size() == 0) {
                System.out.println("게시글이 없습니다");
                return 0;
            }

            System.out.println("  번호  /   제목  ");
            for (Article article : articles) {
                System.out.printf("  %d     /   %s   \n", article.getId(), article.getTitle());
            }
        } else if (cmd.startsWith("article delete")) {

            int id = 0;

            try {
                id = Integer.parseInt(cmd.split(" ")[2]);
            } catch (Exception e) {
                System.out.println("번호는 정수로 입력해");
                return 0;
            }

            SecSql sql = new SecSql();
            sql.append("SELECT COUNT(*) FROM article WHERE id = ?;", id);
            int deleteId = DBUtil.selectRowIntValue(conn, sql);

            if (deleteId == 0) {
                System.out.println(id + "번 게시물 없어.");
            } else {
                SecSql sql2 = new SecSql();
                sql2.append("DELETE FROM article WHERE id = ?;", id);
                DBUtil.delete(conn, sql2);
                System.out.println(id + "번 글이 삭제되었습니다.");
            }

        } else if (cmd.startsWith("article modify")) {

            int id = 0;

            try {
                id = Integer.parseInt(cmd.split(" ")[2]);
            } catch (Exception e) {
                System.out.println("번호는 정수로 입력해");
                return 0;
            }
            SecSql sql = new SecSql();
            sql.append("SELECT COUNT(*) FROM article WHERE id = ?;", id);
            int articleId = DBUtil.selectRowIntValue(conn, sql);

            if (articleId == 0) {
                System.out.println(id + "번 게시물 없어.");
            } else {
                System.out.println("==수정==");
                System.out.print("새 제목 : ");
                String title = sc.nextLine().trim();
                System.out.print("새 내용 : ");
                String body = sc.nextLine().trim();
                SecSql sql2 = new SecSql();
                sql2.append("UPDATE article");
                sql2.append("SET updateDate = NOW(),");
                if (!title.isEmpty()) {
                    sql2.append("title = ?,", title);
                }
                if (!body.isEmpty()) {
                    sql2.append("`body`= ?", body);
                }
                sql2.append("WHERE id = ?;", id);

                DBUtil.update(conn, sql2);
                System.out.println(id + "번 글이 수정되었습니다.");
            }
        } else if (cmd.startsWith("article detail")) {
            int id = 0;
            try {
                id = Integer.parseInt(cmd.split(" ")[2]);
            } catch (Exception e) {
                System.out.println("번호는 정수로 입력해");
                return 0;
            }
            SecSql sql = new SecSql();
            sql.append("SELECT COUNT(*) FROM article WHERE id = ?;", id);
            int articleId = DBUtil.selectRowIntValue(conn, sql);
            if (articleId == 0) {
                System.out.println(id + "번 게시물 없어.");
            } else {

                SecSql sql2 = new SecSql();
                sql2.append("SELECT * FROM article WHERE id = ?;", id);
                Map<String, Object> articleListMap = DBUtil.selectRow(conn, sql2);

//                if (articleListMap.isEmpty()) {
//                    System.out.println(id + "번 게시물 없어");
//                    return 0;
//                }

                Article article = new Article(articleListMap);

                System.out.println("번호 : " + article.getId());
                System.out.println("제목 : " + article.getTitle());
                System.out.println("내용 : " + article.getBody());
                System.out.println("작성시간 : " + article.getRegDate());
                System.out.println("수정시간 : " + article.getUpdateDate());

            }
        }
        return 0;
    }
}

이렇다.

그리고 다시 DB 문제로 넘어갔다.


# a5 데이터베이스 삭제/생성/선택
DROP DATABASE IF EXISTS a5;
CREATE DATABASE a5;
USE a5;

# 부서(dept) 테이블 생성 및 홍보부서 기획부서 추가
SHOW TABLES;

CREATE TABLE dept(
    id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT
    PRIMARY KEY,
    regDate DATETIME NOT NULL,
    `name` VARCHAR(100) NOT NULL
);

INSERT INTO dept (regDate, `name`)
VALUES             (now(), '홍보');

INSERT INTO dept (regDate, `name`)
VALUES             (now(), '기획');


ALTER TABLE dept MODIFY COLUMN `name` VARCHAR(100) NOT NULL UNIQUE;

SELECT *
FROM dept;

# 사원(emp) 테이블 생성 및 홍길동사원(홍보부서), 홍길순사원(홍보부서), 임꺽정사원(기획부서) 추가

CREATE TABLE emp(
    id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT
    PRIMARY KEY,
    regDate DATETIME NOT NULL,
    `name` VARCHAR(100) NOT NULL,
    deptName VARCHAR(100) NOT NULL
    );

INSERT INTO emp (`name`,regDate, deptName)
VALUES            ('홍길동', NOW(), '홍보');

INSERT INTO emp (`name`, regDate, deptName)
VALUES            ('홍길순', NOW(), '홍보');

INSERT INTO emp (`name`, regDate, deptName)
VALUES            ('임꺽정', NOW(), '기획');

SELECT *
FROM emp;


# 홍보를 마케팅으로 변경
SHOW TABLES;

SELECT * FROM emp;
SELECT * FROM dept;

UPDATE dept
SET `name` = '마케팅'
WHERE `name` = '홍보';

UPDATE emp
SET `deptName` = '마케팅'
WHERE `deptName` = '홍보';


# 마케팅을 홍보로 변경
UPDATE dept
SET `name` = '홍보'
WHERE `name` = '마케팅';

UPDATE emp
SET `deptName` = '홍보'
WHERE `deptName` = '마케팅';

# 홍보를 마케팅으로 변경
UPDATE dept
SET `name` = '마케팅'
WHERE `name` = '홍보';

UPDATE emp
SET `deptName` = '마케팅'
WHERE `deptName` = '홍보';
# 구조를 변경하기로 결정(사원 테이블에서, 이제는 부서를 이름이 아닌 번호로 기억)
ALTER TABLE emp ADD COLUMN deptId INT(10) UNSIGNED NOT NULL;

SELECT * FROM emp;

UPDATE emp
SET deptID = 1
WHERE deptName = '마케팅';

UPDATE emp
SET deptID = 2
WHERE deptName = '기획';

ALTER TABLE emp DROP COLUMN deptName;

SELECT * FROM emp;

# 사장님께 드릴 인명록을 생성
SELECT * FROM emp;

# 사장님께서 부서번호가 아니라 부서명을 알고 싶어하신다.
# 그래서 dept 테이블 조회법을 알려드리고 혼이 났다.

SELECT `name`
FROM dept
WHERE id = 2;

# 사장님께 드릴 인명록을 생성(v2, 부서명 포함, ON 없이)
# 이상한 데이터가 생성되어서 혼남

SELECT emp.*, dept.name AS `부서명`
FROM emp
INNER JOIN dept;

# 사장님께 드릴 인명록을 생성(v3, 부서명 포함, 올바른 조인 룰(ON) 적용)
# 보고용으로 좀 더 편하게 보여지도록 고쳐야 한다고 지적받음

SELECT emp.*, dept.name AS `부서명`
FROM emp
INNER JOIN dept
ON dept.id = emp.deptId;


# 사장님께 드릴 인명록을 생성(v4, 사장님께서 보시기에 편한 칼럼명(AS))

SELECT emp.id AS `사원번호`, emp.`name` AS `사원명`, dept.name AS `부서명`
FROM emp
INNER JOIN dept
ON dept.id = emp.deptId;
  • INNER JOIN은 항상 ON과 함께 사용한다. ON = 조건, AS 는 임의의 칼럼명.

이제는 DB도 조금 파야할 필요성을 느꼈다. 언제 뭘 써야되는지가 두루뭉실하게 떠올라서 헷갈린다. 뭘 써야하는지는 기억이 나도 정확한 문법이 기억이 나지 않아서 헤맨다.

다음 문제는 두갠데, 일단 첫번째

DROP DATABASE IF EXISTS mall;

CREATE DATABASE mall;

USE mall;

CREATE TABLE t_shopping(
id INT(5) PRIMARY KEY AUTO_INCREMENT,
userId CHAR(30) NOT NULL,
userPw CHAR(30) NOT NULL,
userName CHAR(30) NOT NULL,
address CHAR(50) NOT NULL,
pname CHAR(50) NOT NULL,
price INT(5) NOT NULL
);

INSERT INTO t_shopping 
SET userId = 'user1',
userPw = 'pass1',
userName = '손흥민',
address = '런던',
pname = '운동화',
price = 1000000;

INSERT INTO t_shopping 
SET userId = 'user2',
userPw = 'pass2',
userName = '설현',
address = '서울',
pname = '코트',
price = 100000;

INSERT INTO t_shopping 
SET userId = 'user3',
userPw = 'pass3',
userName = '원빈',
address = '대전',
pname = '반바지',
price = 30000;

INSERT INTO t_shopping 
SET userId = 'user4',
userPw = 'pass4',
userName = '송혜교',
address = '대구',
pname = '스커트',
price = 15000;

INSERT INTO t_shopping 
SET userId = 'user5',
userPw = 'pass5',
userName = '소지섭',
address = '부산',
pname = '코트',
price = 100000;

INSERT INTO t_shopping 
SET userId = 'user6',
userPw = 'pass6',
userName = '김지원',
address = '울산',
pname = '티셔츠',
price = 9000;

INSERT INTO t_shopping 
SET userId = 'user6',
userPw = 'pass6',
userName = '김지원',
address = '울산',
pname = '운동화',
price = 200000;

INSERT INTO t_shopping 
SET userId = 'user1',
userPw = 'pass1',
userName = '손흥민',
address = '런던',
pname = '코트',
price = 100000;

INSERT INTO t_shopping 
SET userId = 'user4',
userPw = 'pass4',
userName = '송혜교',
address = '울산',
pname = '스커트',
price = 15000;

INSERT INTO t_shopping 
SET userId = 'user1',
userPw = 'pass1',
userName = '손흥민',
address = '런던',
pname = '운동화',
price = 1000000;

INSERT INTO t_shopping 
SET userId = 'user5',
userPw = 'pass5',
userName = '소지섭',
address = '부산',
pname = '모자',
price = 30000;

SELECT *
FROM t_shopping
ORDER BY userName;

# 1. 손흥민의 주문 개수는? ???
SELECT COUNT(*)
FROM t_shopping
WHERE userName = '손흥민';


# 2. 손흥민이 산 상품은? ???
SELECT pname
FROM t_shopping
WHERE userName = '손흥민';


# 3. 스커트를 산 사람은? ???
SELECT *
FROM t_shopping
WHERE pname = '스커트';


# 4. 가장 많이 주문한 사람의 아이디와 이름, 주문개수는? ???
SELECT userId, userName, COUNT(pname) AS orderCount
FROM t_shopping
GROUP BY userId, userName
ORDER BY orderCount DESC
LIMIT 1;


# 5. 소지섭이 사용한 총 금액은? ???
SELECT userName, SUM(price) AS `총액`
FROM t_shopping
WHERE userName = '소지섭';

는 어떻게 풀긴했는데 두번째부터는 좀 어려움을 많이 겪었다.

DROP DATABASE IF EXISTS mall;

CREATE DATABASE mall;

USE mall;

CREATE TABLE t_order(
id INT(5) PRIMARY KEY AUTO_INCREMENT,
userNo INT(5) NOT NULL,
productNo INT(5) NOT NULL
);

CREATE TABLE t_user(
id INT(5) PRIMARY KEY AUTO_INCREMENT,
userId CHAR(200) NOT NULL,
userPw CHAR(200) NOT NULL,
userName CHAR(50) NOT NULL,
addr CHAR(200) NOT NULL
);

CREATE TABLE t_product(
id INT(5) PRIMARY KEY AUTO_INCREMENT,
pname CHAR(100) NOT NULL,
price INT(10) NOT NULL
);


INSERT INTO t_product
SET pname = '운동화',
price = 1000000;

INSERT INTO t_product
SET pname = '코트',
price = 100000;

INSERT INTO t_product
SET pname = '반바지',
price = 30000;

INSERT INTO t_product
SET pname = '스커트',
price = 15000;

INSERT INTO t_product
SET pname = '코트',
price = 100000;

INSERT INTO t_product
SET pname = '티셔츠',
price = 9000;

INSERT INTO t_product
SET pname = '운동화',
price = 200000;

INSERT INTO t_product
SET pname = '모자',
price = 30000;

INSERT INTO t_user
SET userId = 'user1',
userPw = 'pass1',
userName = '손흥민',
addr = '런던';

INSERT INTO t_user
SET userId = 'user2',
userPw = 'pass2',
userName = '설현',
addr = '서울';

INSERT INTO t_user
SET userId = 'user3',
userPw = 'pass3',
userName = '원빈',
addr = '대전';

INSERT INTO t_user
SET userId = 'user4',
userPw = 'pass4',
userName = '송혜교',
addr = '대구';

INSERT INTO t_user
SET userId = 'user5',
userPw = 'pass5',
userName = '소지섭',
addr = '부산';

INSERT INTO t_user
SET userId = 'user6',
userPw = 'pass6',
userName = '김지원',
addr = '울산';


INSERT INTO t_order
SET userNo = 1,
productNo = 1;

INSERT INTO t_order
SET userNo = 2,
productNo = 2;

INSERT INTO t_order
SET userNo = 3,
productNo = 3;

INSERT INTO t_order
SET userNo = 4,
productNo = 4;

INSERT INTO t_order
SET userNo = 5,
productNo = 5;

INSERT INTO t_order
SET userNo = 6,
productNo = 6;

INSERT INTO t_order
SET userNo = 6,
productNo = 7;

INSERT INTO t_order
SET userNo = 1,
productNo = 5;

INSERT INTO t_order
SET userNo = 4,
productNo = 4;

INSERT INTO t_order
SET userNo = 1,
productNo = 1;

INSERT INTO t_order
SET userNo = 5,
productNo = 8;

SELECT * FROM t_user;
SELECT * FROM t_order;
SELECT * FROM t_product;


# 1. 손흥민의 주문 개수는? ???
SELECT t_user.userName, COUNT(t_order.userNo) AS orderCount
FROM t_order
INNER JOIN t_user ON t_order.userNo = t_user.id
WHERE t_user.userName = '손흥민'
GROUP BY t_user.userName;



# 2. 손흥민이 산 상품은? ???
SELECT t_user.userName, t_order.productNo AS '상품넘버'
FROM t_order
INNER JOIN t_user ON t_order.userNo = t_user.id
WHERE t_user.userName = '손흥민';


# 3. 스커트를 산 사람은? ???
SELECT t_product.panme AS '상품명', t_order.productNo AS '상품넘버', t_user.userName AS '유저명'
FROM t_order, t_product, t_user
INNER JOIN t_product ON t_product.id = t_order.productNo
JOIN t_user ON t_user.id = t_order.userId
WHERE t_product.panme = '스커트';
# 실행 안됨.




# 4. 가장 많이 주문한 사람의 아이디와 이름, 주문개수는? ???
SELECT t_user.userName, t_user.id, COUNT(t_order.productNo) AS `상품개수`
FROM t_order
INNER JOIN t_user ON t_order.userNo = t_user.id
GROUP BY t_user.id, t_order.userNo
ORDER BY `상품개수` DESC
LIMIT 1;

# 5. 소지섭이 사용한 총 금액은? ???

겨우겨우 이까지는 했다..

암튼 첫번째 풀이부터 시작해서 약간 고쳐야할 것 들만 써놓겠다.

# 2. 손흥민이 산 상품은? ???
SELECT DISTINCT pname
FROM t_shopping
WHERE userName = '손흥민';

#DISTINCT 중복제거

# 3. 스커트를 산 사람은? ???
SELECT DISTINCT userId, userName
FROM t_shopping
WHERE pname = '스커트';

# 보고 싶은 정보만 골라낼 줄 알아야함.

# COUNT MAX SUM 등은 GROUP으로 사용.

나머지는 조금 다르긴 한데 비슷하다.

의외로 두번째 문제는 내가 생각한 것과 다르게 푸셨다. 그냥 하나하나 조회해서 결과를 보고 넘어갔고 숙제로 JOIN을 사용하라고 하셨다.

일단 글은 여기서 마무리 하겠다.