我正在寻找基于一些用户选择参数创建Postgres查询。
用户将选择商店以及开始和结束年份。一旦提交,我只想显示项目的平均价格,如果它们仅存在于所选的所有年份中。
例如,用户选择2014年的开始日期和2018年的结束日期。项目香蕉功能在所有这些年份,但苹果仅在2014年,2015年和2017年功能。所以我的最终结果将只显示香蕉的平均价格而不是苹果。
到目前为止,这是我开发的查询。我不确定如何最好地实现仅在所有搜索年份中出现的项目被平均的部分。
@sale_averages = Sale.joins(:shops, :items).where('extract(year from season_year) < ? AND extract(year from season_year) > ? ', params[:start_year], params[:end_year])
.where('shops.name = ?', params[:select_shop])
.select('items.name, AVG(sale.price) as price').group('shop.name')
架构
create_table "items", force: :cascade do |t|
t.string "name"
end
create_table "sales", force: :cascade do |t|
t.integer "shop_id"
t.integer "item_id"
t.date "season_year"
t.decimal "price"
end
create_table "shops", force: :cascade do |t|
t.string "name"
end
您可以检查每年有哪些项目的记录。您可以通过检查每个项目的不同年份数是否等于总年数(使用COUNT DISTINCT
)来实现:
number_years = params[:end_year].to_i - params[:start_year].to_i + 1
@sale_averages = Sale.joins(:shops, :items)
.select('items.name, AVG(sale.price) as price')
.where("EXTRACT(year from season_year) BETWEEN #{params[:start_year]} AND #{params[:end_year]}")
.where('shops.name': params[:select_shop])
.group('items.name')
.having("(COUNT(DISTINCT(EXTRACT(year from season_year))) = #{number_years})")
我也使用BETWEEN
而不是<
和>
。我想你想按项目名称而不是商店进行分组(就像你在原始查询中一样)。