반응형
 const jointest = await DB.getRepository(Post)
    .createQueryBuilder("post")
    .leftJoinAndSelect("post.imageFiles", "imageFiles.url")
    .where("post.id <= :id", { id: readedPostId })
    .orderBy({ "post.id": "DESC" })
    .limit(50)
    .getMany();

typeOrm으로 leftjoin후 50개의 객체를 리턴받는 것을 목표로 쿼리를 작성했지만

실제로는 객체가 50개가 리턴되지 않고 적은 숫자가 리턴되었다.

 

그 이유는 이렇게 쿼리를 작성하면 

실제 쿼리는 위의 사진과 같이 Post id가 여러개 중복된 결과를 바탕으로

객체를 만들어서 리턴해주기 때문에

즉 쿼리 결과 50개를 바탕으로 객체를 리턴해주어서 post 50개가 아닌 쿼리결과 50개에 해당하는 데이터를 받는 것이었다.

 

이런 문제를 해결하기 위해서는 조인 후 리밋을 거는 게 아니라

post에 미리 50개를 리밋 걸어서 얻고 그 후 조인을 해야 해결할 수 있다.

 

실제 쿼리문으로 치면 이런식으로 작성을 해야 하는 것이다.

select * from (select id, writer from post order by post.id desc limit 50) as post
left join image_file
on post.id = image_file.postId

 

 

그런데 검색을 하다보니 limit이 아닌 take를 사용하면 이 문제를 해결 할 수 있었다. 

const jointest = await DB.getRepository(Post)
    .createQueryBuilder("post")
    .where("post.id <= :id", { id: readedPostId })
    .orderBy({ "post.id": "DESC" })
    .leftJoinAndSelect("post.imageFiles", "imageFiles.url")
    .take(50)
    .getMany();

typeOrm pagination

https://orkhan.gitbook.io/typeorm/docs/select-query-builder#adding-offset-expression

 

Select using Query Builder - typeorm

There are two types of results you can get using select query builder: entities and raw results. Most of the time, you need to select real entities from your database, for example, users. For this purpose, you use getOne and getMany. However, sometimes you

orkhan.gitbook.io

 

반응형

app.js

var mongoose = require('mongoose');

const { Post } = require("./models")

mongoose.connect("mongodb://localhost:27017/myapp")

mongoose.connection.on("connected", () => {
    console.log("연결 완료");
})

mongoose.connection.on("disconnected", () => {
    console.log("연결 끊김");
})


async function main() {
    await Post.create({
        title: "제목3",
        content: "내용3",
        etc: "etc",
    })
}

main();


async function findList() {
    return await Post.find({})
}

findList().then((res) => {
    console.log(res.map((item) => { return item.title === '제목' }));
})

async function findItem() {
    return await Post.find({ title: "제목2" });
}

findItem().then((res) => {
    console.log(res);
})


async function changeitem() {
    res = await Post.findOneAndUpdate({
        id: '62d4e1b3d6408bbd8909a939',
        title: '12345'
    });

    console.log(res);
}

changeitem();



(async function deleteFun() {
    res = await Post.deleteOne({
        id: "62d4e1e2382904f6f3402a68",
    })
    console.log(res);
})()

 

models/schemas/board.js

const { Schema } = require("mongoose")

const PostSchema = new Schema({
    title: String,
    content: String,
    etc: String,
},
    {
        timestamps: true
    });

module.exports = PostSchema;

 

models/index.js

const mongoose = require("mongoose")
const PostSchema = require("./schemas/board")

exports.Post = mongoose.model("Post", PostSchema);
반응형

소프트웨어 마에스트로 SQL 문제

 

이번에 소프트웨어 마에스트로 코딩테스트를 보게 되었는데

특이하게도 소마 코테에는 mysql과 web 문제가 포함되어 있습니다.

SQL 언어는 MariaDB 와 PostgreSQL 중 선택해서 응시 할 수 있습니다.

 

 

물론 알고리즘 문제에 비해 비중이 적긴 하지만

그래도 이왕 같이 공부하면 언젠가 도움이 될 거라 생각해서

프로그래머스 사이트에 있는 sql 문제 모음을 풀고 정리해봤습니다.

 

 

저도 유튜브로 생활코딩 데이터베이스 수업을 들어본 것 외에는 따로 SQL을 공부해본 적은 없습니다.

SQL을 아직 전혀 모르는 분이더라도

생활코딩 데이터베이스 수업을 한번 듣고

부족한 부분은 구글링하면서 문법을 배우면서

프로그래머스 문제를 풀면 충분히 대비할 수 있을거라 생각합니다.

프로그래머스 문제는 30문제가 좀 안되는데

기본기가 있으면 날잡고 하루정도면 충분히 풀 수 있습니다.

 

 


 

생활코딩 데이터베이스

https://www.youtube.com/watch?v=h_XDmyz--0w&list=PLuHgQVnccGMCgrP_9HL3dAcvdt8qOZxjW 

생활코딩 데이터베이스 수업

 

 

 

 

프로그래머스 SQL 고득점 KIT

https://programmers.co.kr/learn/challenges?tab=sql_practice_kit 

 

코딩테스트 연습

기초부터 차근차근, 직접 코드를 작성해 보세요.

programmers.co.kr

프로그래머스 sql 문제

 

 


프로그래머스 SQL 문제와 답

1.SELECT

1-1. 모든 레코드 조회하기

SELECT * 
FROM ANIMAL_INS 
ORDER BY ANIMAL_ID;

 

1-2. 역순 정렬하기

SELECT NAME, DATETIME 
FROM ANIMAL_INS 
ORDER BY ANIMAL_ID DESC;

 

 

1-3. 아픈 동물 찾기

SELECT ANIMAL_ID, NAME 
FROM ANIMAL_INS 
WHERE INTAKE_CONDITION in ('Sick');

 

 

1-4. 어린 동물 찾기

SELECT ANIMAL_ID, NAME 
FROM ANIMAL_INS 
WHERE INTAKE_CONDITION != 'Aged' 
ORDER BY ANIMAL_ID;

 

 

1-5. 동물의 아이디와 이름

SELECT ANIMAL_ID, NAME 
FROM ANIMAL_INS;

 

 

1-6. 여러 기준으로 정렬하기

SELECT ANIMAL_ID, NAME, DATETIME 
FROM ANIMAL_INS 
ORDER BY NAME, DATETIME DESC;

 

 

1-7. 상위 n개 레코드

SELECT NAME 
FROM ANIMAL_INS 
ORDER BY DATETIME 
LIMIT 1;

mysql에서 row를 n 행만 출력하려면 LIMIT n 을 해주면 됩니다.

특정 구간을 출력하려면 LIMIT x1, x2 해주면 됩니다.

 

 


2. SUM, MAX, MIN

2-1. 최댓값 구하기

SELECT MAX(DATETIME) 
FROM ANIMAL_INS;

 

2-2. 최솟값 구하기

SELECT MIN(DATETIME) 
FROM ANIMAL_INS;

 

2-3. 동물 수 구하기

SELECT COUNT(*) 
FROM ANIMAL_INS;

 

 

2-4. 중복 제거하기

SELECT COUNT(DISTINCT NAME) 
FROM ANIMAL_INS;

mysql DISTINCT 를 이용하면 집합과 같은 효과를 냅니다.

 

 

 


3. GROUP BY

 

3-1. 고양이와 개는 몇 마리 있을까

SELECT ANIMAL_TYPE, COUNT(ANIMAL_ID) 
FROM ANIMAL_INS 
GROUP BY ANIMAL_TYPE 
ORDER BY ANIMAL_TYPE;

 

 

3-2. 동명 동물 수 찾기

SELECT NAME, COUNT(ANIMAL_ID) 
FROM ANIMAL_INS 
WHERE NAME is not null 
GROUP BY NAME 
Having COUNT(NAME) > 1
ORDER BY NAME;
 
 
 

3-3. 입양 시각 구하기(1)

SELECT HOUR(DATETIME), 
COUNT(HOUR(DATETIME)) 
FROM ANIMAL_OUTS 
WHERE (HOUR(DATETIME)>=9 and HOUR(DATETIME)<20)
GROUP BY HOUR(DATETIME) 
ORDER BY HOUR(DATETIME);​
 
 
 

3-4. 입양 시각 구하기(2)

SET @hour := -1;

SELECT (@hour := @hour + 1) as HOUR,
(SELECT COUNT(*) FROM ANIMAL_OUTS 
 WHERE HOUR(DATETIME) = @hour) as COUNT
 FROM ANIMAL_OUTS
 WHERE @hour < 23​

갑자기 띠용 하는 문제입니다.

이정도 문제는 소프트웨어 마에스트로를 준비할 때는 과감히 빼버리셔도..

 

 

 


4. IS NULL

4-1. 이름이 없는 동물의 아이디

SELECT ANIMAL_ID
FROM ANIMAL_INS
WHERE NAME is null
ORDER BY ANIMAL_ID;
 
 
 

4-2. 이름이 있는 동물의 아이디

SELECT ANIMAL_ID
FROM ANIMAL_INS
WHERE NAME IS NOT NULL
ORDER BY ANIMAL_ID;

 

 

4-3. NULL 처리하기

SELECT ANIMAL_TYPE, if(NAME IS NULL,"No name", NAME) , SEX_UPON_INTAKE
FROM ANIMAL_INS;

 

 

 


5. JOIN

 

5-1. 없어진 기록 찾기

SELECT ANIMAL_OUTS.ANIMAL_ID, ANIMAL_OUTS.NAME
FROM ANIMAL_OUTS
LEFT JOIN ANIMAL_INS ON
ANIMAL_OUTS.ANIMAL_ID = ANIMAL_INS.ANIMAL_ID
where (ANIMAL_INS.ANIMAL_ID IS NULL)
ORDER BY ANIMAL_OUTS.ANIMAL_ID;
 

 

5-2. 있었는데요 없었습니다

SELECT ANIMAL_INS.ANIMAL_ID, ANIMAL_INS.NAME
FROM ANIMAL_INS
LEFT JOIN ANIMAL_OUTS
ON ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID
where (ANIMAL_INS.DATETIME > ANIMAL_OUTS.DATETIME)
ORDER BY ANIMAL_INS.DATETIME;

 

 

5-3. 오랜 기간 보호한 동물(1)

SELECT ANIMAL_INS.NAME, ANIMAL_INS.DATETIME
FROM ANIMAL_INS
LEFT JOIN ANIMAL_OUTS
ON ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID
WHERE ANIMAL_OUTS.DATETIME IS NULL
ORDER BY ANIMAL_INS.DATETIME
LIMIT 3;​
 
 
 

5-4.보호소에서 중성화한 동물

SELECT ANIMAL_OUTS.ANIMAL_ID, ANIMAL_OUTS.ANIMAL_TYPE, ANIMAL_OUTS.NAME
FROM ANIMAL_OUTS
INNER JOIN ANIMAL_INS
ON ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID
WHERE ANIMAL_OUTS.SEX_UPON_OUTCOME != ANIMAL_INS.SEX_UPON_INTAKE
ORDER BY ANIMAL_OUTS.ANIMAL_ID;
 

6. String, Date

6-1. 루시와 엘라 찾기

SELECT ANIMAL_ID, NAME, SEX_UPON_INTAKE
FROM ANIMAL_INS
WHERE NAME IN ('Lucy', 'Ella', 'Pickle', 'Rogan', 'Sabrina', 'Mitty')
 
 
 

6-2. 이름에 el이 들어가는 동물 찾기

SELECT ANIMAL_ID, NAME
FROM ANIMAL_INS
WHERE UPPER(NAME) like '%EL%' and ANIMAL_TYPE='Dog'
ORDER BY NAME;

 

 

6-3. 중성화 여부 파악하기

SELECT 
ANIMAL_ID, 
NAME, 
if(SEX_UPON_INTAKE LIKE 'Neutere%' or
SEX_UPON_INTAKE LIKE 'Spayed%','O','X') as '중성화'
FROM ANIMAL_INS
ORDER BY ANIMAL_ID;
 

 

6-4. 오랜 기간 보호한 동물(2)

SELECT ANIMAL_OUTS.ANIMAL_ID,ANIMAL_OUTS.NAME
FROM ANIMAL_OUTS 
INNER JOIN ANIMAL_INS
ON ANIMAL_OUTS.ANIMAL_ID = ANIMAL_INS.ANIMAL_ID
ORDER BY (ANIMAL_OUTS.DATETIME - ANIMAL_INS.DATETIME) DESC
LIMIT 2;​
 
 
 

6-5. DATETIME에서 DATE로 형 변환

SELECT ANIMAL_ID, NAME, MID(DATETIME, 1,10) as '날짜'
FROM ANIMAL_INS
order by ANIMAL_ID;

 

 


 

 

+ Recent posts