我的数据库中有超过 100,000 个不同产品的对象。每个产品有 4-6 个变体。因此,通过迭代所有内容来延迟编辑大量数据并不容易。因此,我试图只获取我需要的确切数量的产品。
到目前为止,我可以获得所有具有尺寸属性“SM”的变体的产品。
挂起的问题是获取所有同时具有尺寸“MD”和“SM”变体的产品。
这是我正在使用的代码 Product.joins(:variants).where('variants.size = ?', 'SM')
我尝试添加 .where('variants.size = ?', 'MD')
到其中,但这确实有效。
最佳答案
这个怎么样
Product.where(
id: Variant.select(:product_id)
.where(size: 'SM')
).where(id: Variant.select(:product_id)
.where(size: 'MD')
)
这应该生成类似于
的内容SELECT products.*
FROM products
WHERE products.id IN (SELECT
variants.product_id
FROM variants
WHERE size = 'SM')
AND products.id IN (SELECT
variants.product_id
FROM variants
WHERE size = 'MD')
因此产品 ID 必须同时存在于两个列表中才能被选中。
此外,这也应该有效(不是 100% 确定)
Product.where(id: Product.joins(:variants)
.where(variants: {size: ['SM', 'MD']})
.group(:id)
.having('COUNT(*) = 2').select(:id)
这应该生成类似的东西
SELECT products.*
FROM products
WHERE
products.id IN ( SELECT products.id
FROM products
INNER JOIN variants
ON variants.product_id = products.id
WHERE
variants.size IN ('SM','MD')
GROUP BY
products.id
HAVING
Count(*) = 2
多一个选择
p_table = Products.arel_table
v_table = Variant.arel_table
sm_table = p_table.join(v_table)
.on(v_table[:product_id].eq(p_table.[:id])
.and(v_table[:size].eq('SM'))
)
md_table = p_table.join(v_table)
.on(v_table[:product_id].eq(p_table.[:id])
.and(v_table[:size].eq('MD'))
)
Product.joins(sm_table.join_sources).joins(md_table.join_sources)
SQL
SELECT products.*
FROM products
INNER JOIN variants on variants.product_id = products.id
AND variants.size = 'SM'
INNER JOIN variants on variants.product_id = products.id
AND variants.size = 'MD'
由于 INNER JOIN,这 2 个连接应该强制执行小型和中型连接
关于ruby-on-rails - Rails 找到有两个具有特定属性的子级的父级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44889960/