문자열을 배열로 입력받아 세로로 읽은 결과를 리턴하라.
public class ReadVertically {
public String readVertically(String[] arr) {
int maxLength=0;
String result = "";
for(String o : arr){
maxLength = Math.max(maxLength,o.length());
}
System.out.println(maxLength);
for(int i=0; i<maxLength; i++){
for(String o : arr){
if(o.length()>i){
result += o.charAt(i);
}
}
}
return result;
}
}
//입력
readVertically.readVertically(new String[]{
"나듕달",
"랏귁아",
"말에",
"싸",
"미"
});
//출력
나랏말싸미듕귁에달아
gitignore
SQL에서 사용하는 단위
기본키(primary key)
외래키(foreign key)
Q: 왜 Properties.java 파일은 .gitignore에 존재할까요?
(Properties class = MYSQL root 비밀번호가 포함 된 class)
A: 비밀번호 노출을 막기 위해
SQL 실제 실행 순서
FROM > ON > JOIN > WHERE > GROUP BY > HAVING >SELECT > DISTINCT >ORDER BY
Field | Type | Null | Key | Default | Extra |
---|---|---|---|---|---|
id | int | No | PK | null | auto_increment |
name | varchar(255) | No | null | ||
varchar(255) | No | null |
CREATE TABLE `user` (
`id` int PRIMARY KEY AUTO_INCREMENT,
`name` varchar(255) not NULL,
`email` varchar(255) not NULL
);
Field | Type | Null | Key | Default | Extra |
---|---|---|---|---|---|
id | int | No | PK | null | auto_increment |
title | varchar(255) | No | null | ||
body | varchar(255) | No | null | ||
created_at | timestamp | No | CURRENT_TIMESTAMP | DEFAULT_GENERATED | |
userId | int | Yes | FK | null |
CREATE TABLE `content` (
`id` int PRIMARY KEY AUTO_INCREMENT,
`title` varchar(255) not NULL,
`body` varchar(255) not NULL,
`created_at` timestamp not NULL DEFAULT CURRENT_TIMESTAMP,
`userId` int,
FOREIGN KEY (`userId`) REFERENCES `user` (`id`)
);
모든 테이블 조회 = "SHOW TABLES;"
USER 테이블 조회 = "DESCRIBE USER;"
CONTENT 테이블 조회 = "DESCRIBE CONTENT;"
처음에 SELECT * FROM USER;
이렇게 하면 되는 줄 알고 헛짓 했다.
SELECT * FROM USER;
는 테이블의 모든 열을 조회하는 것이지 테이블을 조회하는게 아니다.
2-5 Q: user 테이블에서 특정 조건을 가진 데이터를 찾아라.
//1번 방법
SELECT name FROM user WHERE not name='luckykim'
//2번 방법
SELECT name FROM user WHERE name <> 'luckykim'
insert into content (
title,
body,
userid) values(
'홍길동',
'잘생겼다',
(SELECT id From user where name='luckykim'))
cf. 쿼리문 안에 쿼리문 쓰는건 피하는게 좋다. (성능적인 이슈 때문에)
문제에서는 'luckykim'의 id를 알려줘서 사실 이중 쿼리문 사용하지 않아도 됐다.
SELECT user.name AS userName, email, role.name AS roleName
FROM user
LEFT JOIN role
ON user.roleId = role.id;
SELECT user.name, email, role.name
FROM user
LEFT JOIN role
ON user.roleId = role.id;
위 두가지 방법 다 됨.
(TMI. AS를 쓰도록 유도한 문제이지만 오류 case 설정을 하다 보니 문제의 의도가 제대로 구현되지 않아 AS를 안써도 통과는 된다)
첫 시도 (오류)
SELECT category.name FROM content
JOIN user ON userId = user.id WHERE user.name = 'wish'
join content_category on contentId = content.id
join category on categoryId=category.Id
조인이 잘되고 있는지 한단계씩 확인하기 위한 테스트를 해봤다.
//입력
SELECT * FROM user JOIN content ON userId = user.id WHERE user.name = 'wish'
//출력
[{roleId=1, name=wish, roleName=1, created_at=2023-02-01 16:51:03.0, id=1, title=developer proverb, body=Even if the server goes down, there is a backup, userId=1, email=wjwee9@codestates.com}]
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//입력2
SELECT * FROM user JOIN content ON userId = user.id JOIN content_category ON categoryId = content.id WHERE user.name = 'wish'
//출력2
[{roleId=1, name=wish, roleName=1, contentId=1, created_at=2023-02-01 16:55:32.0, id=1, title=developer proverb, body=Even if the server goes down, there is a backup, userId=1, email=wjwee9@codestates.com, categoryId=1},
{roleId=1, name=wish, roleName=4, contentId=2, created_at=2023-02-01 16:55:32.0, id=1, title=developer proverb, body=Even if the server goes down, there is a backup, userId=1, email=wjwee9@codestates.com, categoryId=1}]
위와 같이 join없이 바로 확인해 봐도 'minsanggu' 의 결과가 행1개만 나와서 혼란에 빠졌었다. ( inner join은 교집합 이기 때문에 join을 하면 할수록 더 적어져야 한다고 생각했기 때문 )
하지만 1:many 관계에서 join으로 인해 오히려 행의 갯수가 늘어날 수 있다. (입력2의 경우 같이 user, 같은 content를 갖지만 category만 다른 행이 존재)
첫 시도의 경우 SQL의 실행 순서를 고려하지 않아서 오류가 난 것이었다.
where
은join colum_name on ~~
이후에 사용 가능하다.
아래와 같이 where 순서 바꾸니까 됐다.
SELECT category.name FROM content
JOIN user ON userId = user.id
join content_category on contentId = content.id
join category on categoryId=category.Id WHERE user.name = 'Wish'";
category 기준으로 생각하니 더 간편함.
(맨 끝에서부터 순서대로 JOIN 하자)
SELECT category.name FROM category
join content_category on categoryId = category.id
join content on contentId=content.Id
JOIN user ON userId = user.id
WHERE user.name = 'wish'";
3-2-10. 각 user(컬럼명을 name으로 바꿔라)가 작성한 글의 개수 (컬럼명을 ContentCount로 바꿔라)를 출력하라.
SELECT user.name, count(content.id) AS 'ContentCount'
FROM user
LEFT JOIN content
ON userId = user.id
GROUP BY user.name
처음에 inner join으로 했다가 오류가 나왔다.
content를 하나도 갖고 있지 않은 user가 있기 때문에 오류가 난 것.
Q1 : 프라이머리 키들도 다 낫널 붙여주는게 좋지 않나?
A1 : 어차피 id가 없는 행은 존재할 수 없다. 즉, 낫널은 의미가 없다.