簡體   English   中英

在Rails上執行原始查詢紅寶石

[英]Executing raw query ruby on rails

我想執行以下查詢:

query = "select v.price, v.quantity, p.title, v.product_id from variants v join products p on (v.product_id = p.id) where (v.price,v.product_id) in (select min(price),product_id from variants group by product_id);"

當我在rails控制台中執行results = ActiveRecord::Base.connection.execute(query) ,我得到:

 ActiveRecord::StatementInvalid: SQLite3::SQLException: near ",": syntax error: select v.price, v.quantity, p.title, v.product_id from variants v join products p on (v.product_id = p.id) where (v.price,v.product_id) in (select min(price),product_id from variants group by product_id)

我確信所有逗號都到位,並且至少對於Oracle來說,該語句寫得很好。 我的錯誤在哪里?

似乎sqlite3不會對具有多個值的in-operator where (v.price,v.product_id) in (select min(price),product_id...where (v.price,v.product_id) in (select min(price),product_id...

通過討論,后面的問題是:

我需要獲得每個產品的最低價格(以變體形式)以及名稱(以產品形式)和數量(以變體形式)

基於此,我推薦以下SQL語句:

SELECT min(`v`.`price`) AS 'min_price', `v`.`quantity`, `p`.`title`, `v`.`product_id` FROM `variants` AS 'v' INNER JOIN `products` AS 'p' ON (`v`.`product_id` = `p`.`id`) GROUP BY `product_id`

或人類可讀版本中的相同陳述:

SELECT 
  min(`v`.`price`) AS 'min_price', 
  `v`.`quantity`, `p`.`title`, `v`.`product_id`
FROM `variants` AS 'v' 
INNER JOIN `products` AS 'p' 
  ON (`v`.`product_id` = `p`.`id`) 
GROUP BY `product_id`

我不使用滑軌和活動記錄,而是使用續集來獲取此解決方案。 這是我測試代碼的完整腳本:

require 'sequel'

DB = Sequel.sqlite('test.db')
Sequel.extension :core_extensions
Sequel.extension :pretty_table

#if called 2nd time with a db-file
DB.drop_table(:variants) if DB.table_exists?(:variants)
DB.drop_table(:products) if DB.table_exists?(:products)

DB.create_table :products do |t| 
  primary_key :id
  t.string :title 
  t.string :description 
  t.timestamps null: false 
end 
DB.create_table :variants do |t| 
  primary_key :id
  t.boolean :is_active 
  t.integer :price 
  t.integer :quantity 
  t.timestamps null: false 

  foreign_key :product_id, :products
end 

class Product < Sequel::Model; end
class Variant < Sequel::Model; end

10.times do |g| 
  Product.create(title: "Prod %02i" % g, description: "Who Cares..") 
end 

 100.times do |c| 
   Variant.create(
    price: (rand(100)).ceil, quantity: (rand(10).ceil).floor , 
    product_id: Product[rand(1..10).floor].id
   ) 
 end

puts DB.tables

sel = DB[:variants.as(:v)]
  .select(Sequel.function(:min,:v__price).as(:min_price), :v__quantity, :p__title, :v__product_id)
  .join(:products.as(:p), :v__product_id => :p__id)
  .group_by(:product_id)

puts sel.sql

Sequel::PrettyTable.print(sel)

結果是:

SELECT min(`v`.`price`) AS 'min_price', `v`.`quantity`, `p`.`title`, `v`.`product_id` FROM `variants` AS 'v' INNER JOIN `products` AS 'p' ON (`v`.`product_id` = `p`.`id`) GROUP BY `product_id`
+---------+----------+--------+-------+
|min_price|product_id|quantity|title  |
+---------+----------+--------+-------+
|        1|         1|       5|Prod 00|
|       12|         2|       9|Prod 01|
|       21|         3|       6|Prod 02|
|        1|         4|       0|Prod 03|
|       34|         5|       8|Prod 04|
|       11|         6|       8|Prod 05|
|       14|         7|       9|Prod 06|
|        7|         8|       8|Prod 07|
|       11|         9|       8|Prod 08|
|       21|        10|       8|Prod 09|
+---------+----------+--------+-------+

(執行時值可能有所不同,數據創建中會有隨機值)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM