how to select/find the table data along with the latest associated (many to many) data
我的表中具有以下关系
item.rb
1 | has_one :item_shipping_detail |
item_shipping_detail.rb
1 2 | belongs_to :item has_many :shipping_statuses |
status.rb
1 | belongs_to :item_shipping_detail |
例如数据
项目
1 2 | id title city state country 1 Title1 Nagpur Maharashtra India |
item_shipping_details
1 2 | id item_id price description 1 1 10 Electronic |
状态
1 2 3 4 | 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_shipping_details,状态
1 2 | 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
尝试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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兼容性设置或其他原因),我将继续他的查询。
使用DISTINCT ON(PostgreSQL扩展名):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 |
还要考虑标准语法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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 |
试试这个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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 |
事实证明,您正在使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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 |
注意:要优化子查询和联接,必须正确索引
如果在
您必须在状态中包含"内容",以便您选择最新状态,例如到达日期等。在提供该额外的列之前,无法回答您的问题。