![](/img/trans.png)
[英]Ruby on Rails - How Do I Added a Where Clause to My Raw SQL Query?
[英]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.