我有3张桌子,
问题
|id|subject|done_ratio|
-----------------------
|1 |test | 50 |
|2 |test1 | 0 |
|3 |test3 | 10 |
期刊
|id|issue_id|notes|created_on |
---------------------------------------
|1 |1 |NULL |2017-09-29 16:35:09|
|2 |3 |test |2017-09-28 16:35:09|
期刊详情
|id|journal_id|prop_key |old_value|value|
------------------------------------------
|1 |1 |done_ratio|0 |50 |
基本上,有3种型号。
问题
has_many :journals
杂志
belongs_to :issue
has_many :journal_details
JournalDetail
belongs_to :journal
Journals
和Journal details
表用于维护Issue
历史记录。
如果更新某个问题属性,则会为每个更新的属性创建journal
条目以及journal details
条目。如果只有一个注释添加到issue
,则只会使用该注释创建journal
条目。
如何在今天之前获取问题列表以及done_ratio
的值,如果找不到则0
我可以先获取所有问题,然后在今天之前获取done_ratio
值,在每个问题的单独查询中。
发现问题
issues = Issue.all
在今天之前为每个问题找到done_ratio
journal = issue.journals.joins(:details).where("journal_details.prop_key ='done_ratio' AND DATE(journals.created_on) = ?", Date.today).order('journals.created_on asc').limit(1).first
last_done_ratio = journal.details.where(prop_key: 'done_ratio').first.old_value.to_f unless journal.blank?
但这会增加加载时间。所以,我想在一个查询中做到这一点。
合并可能在这里工作,但不知道如何。
任何帮助都将不胜感激。
答案 0 :(得分:1)
您可以使用以下查询在今天之前找到问题列表以及done_ratio的值:
Issue
.joins(journals: :journal_details)
.where(journal_details: { prop_key: 'done_ratio' })
.where("DATE(journals.created_on) = ?", Date.today)
.order('journals.created_on asc')
它不会返回没有与prop_key
'done_ratio'相关联的期刊详细信息的问题。如果您还需要解决没有'done_ratio'详细信息的问题,那么您需要使用OUTER JOIN
:
Issue
.joins("LEFT OUTER JOIN journals ON issues.id = journals.issue_id")
.joins("LEFT OUTER JOIN journal_details ON journals.id = journal_details.journal_id")
.where(journal_details: { prop_key: 'done_ratio' })
.where("DATE(journals.created_on) = ?", Date.today)
.order('journals.created_on asc')
答案 1 :(得分:0)
我试过这个:
Issue.select('issues.id, issues.subject, journal_details.old_value as done_ratio')
.left_outer_joins(journals: [:journal_details])
.where('journal_details.prop_key = ?', 'done_ratio')
.where('journals.created_at < ?', Time.now)
.order('journals.created_at DESC')
但这不符合您的需要 我会把它留在这里,以便人们知道如何不这样做。
答案 2 :(得分:0)
这个简单的SQL查询可以帮助您实现所需的结果。
http://sqlfiddle.com/#!17/54dcb/3
SELECT i.id, COALESCE(done_ratio,'0')
FROM issues i left join (
select j.issue_id, row_number() OVER (ORDER BY j.created_on desc) AS rank_index,
jd.new_value done_ratio
FROM Journals j
inner join journal_detail jd
on j.id = jd.journal_id
AND jd.prop_key = 'done_ratio' -- We are interest only in 'done_ratio' only
AND j.created_on < CURRENT_DATE -- and which changed before today -- TODO check for time precision
) last_day_done
ON i.id = last_day_done.issue_id and rank_index = 1 --Only join with first row (most recent)
这可能需要您在表上创建其他索引。