Active Record 방법 및 SQL 요약 표

7544 단어 RailsSQLtech

개시하다


많은 Rails 초보자들이 SQL 문구에 신경을 쓰지 않고 Active Record를 사용하고 있다고 생각합니다.그러나 디버그 작업과 복잡한 선별에서 직접적인 SQL 문구를 활용할 기회가 그만큼 많고 실행된 SQL을 이해하지 못한 채 자신도 모르게 비효율 코드를 쓸 수도 있다.
따라서 이 문서에서는 Active Reocord 메서드에서 수행된 SQL 문을 요약합니다.

메서드 및 SQL 문


find


User.find(1)
# SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1

User.find([2,3,4])
# SELECT `users`.* FROM `users` WHERE `users`.`id` IN (2, 3, 4)
find 방법에서'id에 파라미터가 있는 기록을 꺼내기'라는 SQL을 실행했습니다.
지정된 id가 단수일 경우 SQL 문에는 LIMIT 1가 첨부되지만 배열에 여러 개를 지정할 때는 첨부되지 않습니다.

find_by


User.find_by(id:3)
# SELECT `users`.* FROM `users` WHERE `users`.`id` = 3 LIMIT 1

User.find_by(id:[3,4,6])
# SELECT `users`.* FROM `users` WHERE `users`.`id` IN (3, 4, 6) LIMIT 1
find_by 방법은 열의 이름을 지정하고 기록을 꺼냅니다.수조를 조건 산열에 전달할 수 있지만 LIMIT 1이 추가되어 기록 하나만 호출할 수 있습니다.

where


User.where(email:"[email protected]")
# SELECT `users`.* FROM `users` WHERE `users`.`email` = '[email protected]'

Client.where(created_at: (Time.now.midnight - 1.day)..Time.now.midnight)
# SELECT * FROM clients 
WHERE (clients.created_at BETWEEN '2008-12-21 00:00:00' AND '2008-12-22 00:00:00')
where 방법은 문자와 같이 SQL의 WHERE 문장의 부분에 해당한다.

order


User.order(:username)
# SELECT `users`.* FROM `users` ORDER BY `users`.`username
order 방법에서 SQL을 실행하는 ORDER BY 문장은 지정한 속성의 상승 순서에 따라 기록을 정렬한다.

first,last


User.first
# SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1

User.last
# SELECT `users`.* FROM `users` ORDER BY `users`.`id` DESC LIMIT 1
first 방법은 SQL을 실행합니다. 이 SQL은 id에서 승차순으로 배열된 기록의 첫 번째 기록을 추출합니다.last는 내림차순의 첫 번째입니다.

save,update


user = User.find(2)
user.username = "test"
user.save

# UPDATE `users` 
SET `users`.`updated_at` = '2021-05-09 07:08:50', `users`.`username` = 'test' 
WHERE `users`.`id` = 2
save 방법에서 실례 변수가 변경되면 업데이트된 SQL의 UPDAATE 문장을 실행합니다.

select, pluck


User.select(:username)
# SELECT `users`.`username` FROM `users`
select 방법은 원추형에서만 대상열을 꺼냅니다.pluck도 같은 SQL 문장을 발행했지만, 다른 점은 지정한 열 값의 배열을 되돌려 주는 것이다.
User.select("date(created_at) as ordered_date")
# SELECT date(created_at) as ordered_date FROM `users`
또한 문자열에서 as를 사용하는 조건을 전달하여 SQL의 함수인 DATE의 매개 변수를 전달하는createordered at날짜라는 다른 이름을 얻을 수 있습니다.

destroy


User.find(3).destroy
# DELETE FROM `profiles` WHERE `profiles`.`id` = 3
Destory 메서드에서 SQL의 DELETE 문을 실행합니다.

limit, offset


User.limit(2).to_sql
# "SELECT `users`.* FROM `users` LIMIT 2"
limit 방법은 지정된 건수의 기록만 추출한다.
User.offset(2).limit(3).to_sql
# "SELECT `users`.* FROM `users` LIMIT 3 OFFSET 2"
offset 방법은 기록을 되돌리기 전에 건너뛴 기록 수를 지정할 수 있습니다.
위의 코드는 두 개의 기록을 건너뛰고 id=3에서 세 개의 기록을 얻습니다.
이런 것들을 조합해서 페이지 조합 기능을 실현할 수도 있다.
예를 들어 페이지 단자에 사용되는gemkaminari를 사용할 때
User.page(3).per(5)
# SELECT `users`.* FROM `users` LIMIT 5 OFFSET 10
이러한 SQL을 릴리즈합니다.

exsits?


User.exists?(id:1)
# SELECT 1 AS one FROM `users` WHERE `users`.`id` = 1 LIMIT 1
exists?방법은 조건을 충족시키는 산열된 기록이 있는지 확인하는 방법이다.
WHERE 희구를 봤어요.대상 테이블에서 조건에 맞는 기록을 선별합니다.그리고 1 AS one에서 알 수 있듯이 1을 다른 이름인'one'로 지어 꺼낸다.

group, count ,having


User.select("date(updated_at) as date, sum(id)").group(:date)

# SELECT date(updated_at) as date, sum(id) 
FROM `users` 
GROUP BY `date`
User 업데이트일의 모든 모음에서 업데이트일, 모음 id의 합계를 찾을 때 상기 SQL 문장을 발행합니다.
User.group("date(updated_at)").count

# SELECT COUNT(*) AS count_all, 
date(updated_at) AS date_updated_at 
FROM `users` GROUP BY date(updated_at)
상기에서 그룹그룹방법과count방법을 통해 업데이트일의 소장기록수와 업데이트일을 얻기 위해 SQL문구를 발행한다.
User.select("date(updated_at) as date, sum(id)").group(:date).having("sum(id)>10")

# SELECT date(updated_at) as date, sum(id) 
FROM `users` 
GROUP BY `date` HAVING (sum(id)>10)
having 방법을 사용하여 취합된 결과에 대해 조건을 지정하는 HAVING 문구를 추가한다.

joins/left_outer_joins


다음 두 개의 책상이 있다고 가정해 보세요.
Owner table
id
ownername
1
ichijo
2
jiro
3
saburo
Dog table
id
owner_id
dogname
1
1
pochi
2
2
maru
3
2
hachi
4
4
ken
SELECT * FROM owners INNER JOIN dogs ON owners.id = dogs.owner_id;
INNER JOIN을 이렇게 실행할 때 조합 키로 하는 각 테이블의 키 값 중 두 테이블에 존재하는 값만 결합된다.
위의 SQL 문에서 각 키의 공통 값은 1,2에 불과하므로 Dog 테이블부터 owner아이디는 1, 2 테이블, 오워너표는 아이디는 1, 2 테이블을 결합해 다음과 같은 테이블을 만든다.
id
ownername
id
owner_id
dogname
1
ichiro
1
1
pochi
2
jiro
2
2
maru
2
jiro
3
2
hachi
SELECT * FROM owners LEFT OUTER JOIN dogs ON owners.id = dogs.owner_id;
한편, OUTER JOIN의 경우 INNER JOIN을 통해 연결된 기록 외에 기준표(LEFT OUTER JOIN의 경우 왼쪽 표)가 있는 키값을 결합한 표도 있다.
이번 경우 기준 Owner표의 데이터를 모두 취득하고 이에 대응하는 Dogs표의 기록이 결합된 것이다.
id
ownername
id
owner_id
dogname
1
ichiro
1
1
pochi
2
jiro
2
2
maru
2
jiro
3
2
hachi
3
saburo
null
null
null
이렇게 하면 기준표의 기록은 모두 얻었고 대응하는 기록이 없는 부분은 비어 있다.
각 결합에 대한 Active Record 방법은 다음과 같습니다.
Product.joins(:reviews)

# SELECT `products`.* FROM `products` 
INNER JOIN `reviews` 
ON `reviews`.`product_id` = `products`.`id`
Product 모델은 Reviews 모델has와 비교만약 many의 관계가 있다면, Joins 방법에서 내부 결합을 하는 INNER JOIN 문장을 호출합니다.
Product.left_outer_joins(:reviews)

# SELECT `products`.* FROM `products` 
LEFT OUTER JOIN `reviews` 
ON `reviews`.`product_id` = `products`.`id`
left_outer_join 방법에서 왼쪽 표를 기준으로 하는 OUTER JOIN 문은 라고 부른다.
또한,joins,leftouter_joins 방법을 사용할 때 발행된 SQL 문장에서 알 수 있듯이 SELECT를 통해 합병 목표 표 데이터를 얻지 못했다.select 방법을 사용하면 다음과 같이 모든 결합된 열 데이터를 얻을 수 있습니다.
Product.select("*").joins(:reviews)

# SELECT * FROM `products` 
INNER JOIN `reviews` ON 
`reviews`.`product_id` = `products`.`id`


Product.select("*").left_outer_joins(:reviews)

# SELECT * FROM `products` 
LEFT OUTER JOIN `reviews` 
ON `reviews`.`product_id` = `products`.`id`

참고 자료


Active Record 쿼리 인터페이스
SQL 소인도 알 수 있는 시계 결합(inner join과 outer join)
SQL 0에서 시작하는 데이터베이스 작업

좋은 웹페이지 즐겨찾기