我的表格中有以下关系
item.rb的
has_one :item_shipping_detail
item_shipping_detail.rb
belongs_to :item
has_many :shipping_statuses
status.rb
belongs_to :item_shipping_detail
实施例。数据
项
id title city state country
1 Title1 Nagpur Maharashtra India
item_shipping_details
id item_id price description
1 1 10 Electronic
以下状态
id item_shipping_detail_id status_city status_state status_country created_at
1 1 Mumbai Maharashtra India 2012-01-09 07:58:16
2 1 Akola Maharashtra India 2012-01-10 07:58:16
3 1 Nagpur Maharashtra India 2012-01-11 07:58:16
我希望使用单个查询获得以下结果(item,item_shipping_details,状态(LATEST or MAX)
)
id title city state country price description status_city status_state status_country
1 Title1 Nagpur Maharashtra India 10 Electronic Nagpur Maharashtra India
JYI: - 我正在使用Rails 2.3.8
答案 0 :(得分:4)
尝试:
select i.id,
i.title,
i.city,
i.state,
i.country,
d.price,
d.description,
s.status_city,
s.status_state,
s.status_country
from items i
left join item_shipping_details d on i.id = d.item_id
left join
(select s1.* from statuses s1
where not exists
(select * from statuses s2
where
s2.item_shipping_detail_id = s1.item_shipping_detail_id
and s2.created_at> s1.created_at) ) s
on d.id = s.item_shipping_detail_id
subselect上的where子句筛选出有新记录的记录。这实际上与Mark Bannister的查询(在我的Postgresql 9.1数据库上工作正常)相同,但不使用分区函数。
它可能没有分区功能那么高效,所以如果你可以解决为什么你的运行没有运行(可能是8.4兼容性设置或什么?)我会继续他的查询。
答案 1 :(得分:2)
使用DISTINCT ON,postgresql扩展名:
select distinct on(i.id, d.id)
i.id,
i.title,
i.city,
i.state,
i.country,
d.price,
d.description,
s.status_city,
s.status_state,
s.status_country
from items i
left join item_shipping_details d on i.id = d.item_id
left join statuses s on s.item_shipping_detail_id = d.id
order by i.id, d.id, s.created_at desc
还要考虑标准语法:
select * from (
select i.id,
i.title,
i.city,
i.state,
i.country,
d.price,
d.description,
s.status_city,
s.status_state,
s.status_country,
row_number() over(partition by d.id, i.id order by s.created_at desc) as rn
from items i
left join item_shipping_details d on i.id = d.item_id
left join statuses s on s.item_shipping_detail_id = d.id
) tab where tab.rn = 1
答案 2 :(得分:0)
您必须在状态中加入“内容”,以便选择最新状态,例如到达日期等。在提供额外的列之前,无法回答您的问题。
答案 3 :(得分:0)
事实证明您使用8.3.8
(来自对已删除答案的评论),您无法使用row_number()
。这意味着我倾向于加入聚合子查询以确定哪条记录是最新的。有点像...
SELECT
i.id,
i.title,
i.city,
i.state,
i.country,
d.price,
d.description,
s.status_city,
s.status_state,
s.status_country
FROM
items i
LEFT JOIN
item_shipping_details d
ON i.id = d.item_id
LEFT JOIN
(SELECT item_shipping_detail_id, MAX(created_at) AS created_at FROM statuses GROUP BY item_shipping_detail_id) lookup
ON lookup.item_shipping_detail_id = d.id
LEFT JOIN
statuses s
ON s.item_shipping_detail_id = lookup.item_shipping_detail_id
AND s.created_at = lookup.created_at
注意: 要优化子查询和连接,需要对statuses
表进行适当的索引; (item_shipping_detail_id, created_at)
如果您在(item_shipping_detail_id, id)
上有索引,并且可以保证较高的id
始终表示记录比具有较低{{1}的记录更新},可以在我的查询中用id
替换created_at
的出现。
答案 4 :(得分:0)
试试这个
select distinct on(i.id, d.id)
i.id,
i.title,
i.city,
i.state,
i.country,
d.price,
d.description,
s.status_city,
s.status_state,
s.status_country
from items i
left join item_shipping_details d on i.id = d.item_id
left join statuses s on s.item_shipping_detail_id = d.id
where s.id = (select Max(id) as id from statuses where item_shipping_detail_id = d.id)
order by i.id, d.id desc