[SQL] 협회를 통해 쿼리는 가장 최근의 기록으로 제한 난간?
SQL협회를 통해 쿼리는 가장 최근의 기록으로 제한 난간?
class User
has_many :books
나는 반환하는 쿼리를해야합니다 :
그의 가장 최근의 책이 사용자 : 완전한 => 사실. 사용자의 가장 최근의 책이있는 경우 즉 : 전체 => 허위, 나는 내 결과에서 그들을 원하지 않는다.
내가 지금까지 가지고
User.joins(:books).merge(Book.where(:complete => true))
이는 약속 시작하지만 나에게 내가 원하는 결과를 제공하지 않습니다. 내가 .order ( "created_on 내림차순")을 추가하는 시도했습니다. 제한 (1) 나는 많은 기대하고 때 위의 쿼리의 끝 그러나 나는 단지 하나의 결과로 끝날.
감사!
해결법
-
==============================
1.당신이 @의 rubyprince의 루비 솔루션으로 이동하지 않을 경우이는 하위 쿼리를 필요로하기 때문에 그것은 간단한 형태의에서 액티브 처리 할 수있는 것보다 더 복잡한 DB 쿼리는 사실이다. 여기에 내가 완전히 쿼리와 함께이 작업을 수행 할 방법은 다음과 같습니다
당신이 @의 rubyprince의 루비 솔루션으로 이동하지 않을 경우이는 하위 쿼리를 필요로하기 때문에 그것은 간단한 형태의에서 액티브 처리 할 수있는 것보다 더 복잡한 DB 쿼리는 사실이다. 여기에 내가 완전히 쿼리와 함께이 작업을 수행 할 방법은 다음과 같습니다
SELECT users.* FROM users INNER JOIN books on books.user_id = users.id WHERE books.created_on = ( SELECT MAX(books.created_on) FROM books WHERE books.user_id = users.id) AND books.complete = true GROUP BY users.id
다음을 수행 할 액티브 나는이 점을 변환하려면 :
class User scope :last_book_completed, joins(:books) .where('books.created_on = (SELECT MAX(books.created_on) FROM books WHERE books.user_id = users.id)') .where('books.complete = true') .group('users.id') end
그런 다음 다음을 수행하여 마지막으로 완성 된 책이있는 모든 사용자의 목록을 얻을 수 있습니다 :
User.last_book_completed
-
==============================
2.이것은 약간의 오버 헤드를 추가하지만 복잡성을 저장하고 중요한 때 증가 나중에 속도.
이것은 약간의 오버 헤드를 추가하지만 복잡성을 저장하고 중요한 때 증가 나중에 속도.
책에 "most_recent"열을 추가합니다. 확실히 당신은 인덱스를 추가 확인하십시오.
class AddMostRecentToBooks < ActiveRecord::Migration def self.change add_column :books, :most_recent, :boolean, :default => false, :null => false end add_index :books, :most_recent, where: :most_recent # partial index end
그런 다음 책을 저장, 업데이트 most_recent
class Book < ActiveRecord::Base on_save :mark_most_recent def mark_most_recent user.books.order(:created_at => :desc).offset(1).update_all(:most_recent => false) user.books.order(:created_at => :desc).limit(1).update_all(:most_recent => true) end end
지금, 당신의 쿼리에 대한
class User < ActiveRecord::Base # Could also include and preload most-recent book this way for lists if you wanted has_one :most_recent_book, -> { where(:most_recent => true) }, :class_name => 'Book' scope :last_book_completed, -> { joins(:books).where(:books => { :most_recent => true, :complete => true }) end
이것은 당신이이처럼 쓸 수있는 결과는 다른 범위에서 사용할 수있는 관계이다.
User.last_book_completed
-
==============================
3.나는 최근에 비슷한 문제를 가로 질러 와서 여기서 나는 그것을 해결하는 방법입니다 :
나는 최근에 비슷한 문제를 가로 질러 와서 여기서 나는 그것을 해결하는 방법입니다 :
most_recent_book_ids = User.all.map {|user| user.books.last.id } results = User.joins(:books).where('books.id in (?) AND books.complete == ?', most_recent_book_ids, true).uniq
우리는 액티브 방식 (별도의 SQL)을 사용하는 사용자를위한 책의 부분 집합 고려할 때 (등, 성, 마지막 n 책을, ...)을 다시 사용할 수 있습니다이 방법. 당신은 마지막 'UNIQ'원인은, 그렇지 않으면 각 사용자가 두 번 나타납니다 필요합니다 ..
-
==============================
4.나는 하나의 쿼리에서 그것을 할 수있는 방법을 생각하지 못할하지만 당신은 할 수 있습니다 :
나는 하나의 쿼리에서 그것을 할 수있는 방법을 생각하지 못할하지만 당신은 할 수 있습니다 :
User.all.select { |user| user.books.order("created_at desc").limit(1).complete }
-
==============================
5.여기에 범위를 사용해야합니다 - 그들은 당신의 인생을 훨씬 간단하게 만들 것입니다 (이것은 rails3의 예입니다)
여기에 범위를 사용해야합니다 - 그들은 당신의 인생을 훨씬 간단하게 만들 것입니다 (이것은 rails3의 예입니다)
당신의 book.rb 모델에서
scope :completed, where("complete = ?", true) scope :recent, order("created_on ASC")
그럼 당신은 당신이 원하는 것을 얻을 User.books.recent.completed를 호출 할 수 있습니다
-
==============================
6.팬의 대답 끌 수 있으나 왼쪽에 기반 대신 내부 조인의 조인 없으며 그룹화 :
팬의 대답 끌 수 있으나 왼쪽에 기반 대신 내부 조인의 조인 없으며 그룹화 :
scope :with_last_book_complete, -> { subquery = Book.select(:id) .where("books.user_id = users.id") .order(created_at: :desc).limit(1) joins(<<-SQL).where(books: { complete: true }) LEFT JOIN books ON books.user_id = users.id AND books.id = (#{subquery.to_sql}) SQL }
from https://stackoverflow.com/questions/5247886/rails-query-through-association-limited-to-most-recent-record by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 어떻게 INFORMATION_SCHEMA를 사용하여 기본 제약 조건을 찾을 수 있습니까? (0) | 2020.06.22 |
---|---|
[SQL] 어떻게 말끔를 사용하여 효율적으로 집계 개체를 선택합니까? (0) | 2020.06.22 |
[SQL] 각 행에 대해 MySQL을 자동 저장 날짜 (0) | 2020.06.22 |
[SQL] ALL DATETIME ISO 8601 (0) | 2020.06.22 |
[SQL] 기록이 존재하지 않는 경우에만 테이블에 SQL 삽입 [중복] (0) | 2020.06.22 |