2

我的表格中有以下关系

项目.rb

has_one :item_shipping_detail

item_shipping_detail.rb

belongs_to  :item
has_many :shipping_statuses

状态.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

(LATEST or MAX)我想要使​​用单个查询的以下结果(item、item_shipping_details、status )

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

4

5 回答 5

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

子选择上的 where 子句过滤掉任何有更新记录的记录。这实际上与 Mark Ba​​nnister 的查询相同(在我的 Postgresql 9.1 数据库上运行良好),但不使用分区函数。

它可能没有分区函数那么有效,所以如果你能弄清楚为什么你的函数没有运行(可能是 8.4 兼容性设置或其他什么?)我会去他的查询。

于 2012-01-20T18:58:35.747 回答
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
于 2012-01-23T10:39:38.590 回答
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
于 2012-01-23T16:19:47.587 回答
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 总是意味着记录比具有 lower 的记录更新id,您可以在我的查询中替换出现的created_atwith 。id

于 2012-01-23T12:16:53.247 回答
0

您必须在状态中包含“某些内容”,以便您可以选择最新状态,例如到达日期左右。在您提供额外的专栏之前,无法回答您的问题。

于 2012-01-11T08:45:06.460 回答