我如何重构一个查询,在该查询中我根据与另一个 table 的关系对产品进行排序
How do I refactor a query where I sort products by its relationship from another table
我有这个查询似乎在 pgAdmin 中有效。但是,当我尝试将其翻译为使用 scuttle 时,我得到了一个包含整个 case 语句的大量查询片段。如何重构此查询以便我可以在 Arel 中使用它?
SELECT products.*, case when
(select custom_fields.value_text
from custom_fields
where custom_fields.custom_field_definition_id = 4
and custom_fields.table_record_id = products.id and custom_fields.belongs_to_table = 'product') is null
then 'stopped'
when
(select custom_fields.value_text
from custom_fields
where custom_fields.custom_field_definition_id = 4
and custom_fields.table_record_id = products.id and custom_fields.belongs_to_table = 'product') is not null
then (select custom_fields.value_text from custom_fields where custom_fields.custom_field_definition_id = 4
and custom_fields.table_record_id = products.id and custom_fields.belongs_to_table = 'product')
end as sorted
from products
order by sorted
其他信息:我创建了一个显示预期行为的 sqlite 数据库,可用于进一步的实验。
https://github.com/bigos/rails-sorting/blob/master/README.org
初步结论:我找到了一种获得预期结果的方法,但不能再与 Active Record 方法一起使用。幸运的是,我找到了如何对哈希数组进行分页。
最佳解决方案:如果我将我的代码作为子查询按顺序排列,我可以return正确的活动记录关系。
SELECT products.*
FROM products
ORDER BY (case when
(select custom_fields.value_text
from custom_fields
where custom_fields.custom_field_definition_id = 4
and custom_fields.table_record_id = products.id and custom_fields.belongs_to_table = 'product') is null
then 'stopped'
when
(select custom_fields.value_text
from custom_fields
where custom_fields.custom_field_definition_id = 4
and custom_fields.table_record_id = products.id and custom_fields.belongs_to_table = 'product') is not null
then (select custom_fields.value_text from custom_fields where custom_fields.custom_field_definition_id = 4
and custom_fields.table_record_id = products.id and custom_fields.belongs_to_table = 'product')
end )
我不知道你在使用其他工具时遇到了什么问题 and/or Active Record 但下面的查询应该是等效的并且可能更快:
select p.*, coalesce(cf.value_text, stopped) as sorted
from
products p
left outer join custom_fields cf
on cf.table_record_id = p.id
and cf.belongs_to_table = 'product'
and cf.custom_field_definition_id = 4
order by sorted
此类查询是尽可能避免此类 "custom fields" 表的原因之一。
另一种与您的原始方法非常接近的替代方法是在 coalesce
中使用标量子查询。您甚至可能更喜欢这种方式,因为如果子查询有某种方式 return 多个值,它会导致错误。
select
p.*,
coalesce(
(
select custom_fields.value_text
from custom_fields cf
where
f.table_record_id = p.id
and cf.custom_fields.belongs_to_table = 'product'
and cf.custom_field_definition_id = 4
),
'stopped'
) as sorted
from products p
order by sorted
我有这个查询似乎在 pgAdmin 中有效。但是,当我尝试将其翻译为使用 scuttle 时,我得到了一个包含整个 case 语句的大量查询片段。如何重构此查询以便我可以在 Arel 中使用它?
SELECT products.*, case when
(select custom_fields.value_text
from custom_fields
where custom_fields.custom_field_definition_id = 4
and custom_fields.table_record_id = products.id and custom_fields.belongs_to_table = 'product') is null
then 'stopped'
when
(select custom_fields.value_text
from custom_fields
where custom_fields.custom_field_definition_id = 4
and custom_fields.table_record_id = products.id and custom_fields.belongs_to_table = 'product') is not null
then (select custom_fields.value_text from custom_fields where custom_fields.custom_field_definition_id = 4
and custom_fields.table_record_id = products.id and custom_fields.belongs_to_table = 'product')
end as sorted
from products
order by sorted
其他信息:我创建了一个显示预期行为的 sqlite 数据库,可用于进一步的实验。
https://github.com/bigos/rails-sorting/blob/master/README.org
初步结论:我找到了一种获得预期结果的方法,但不能再与 Active Record 方法一起使用。幸运的是,我找到了如何对哈希数组进行分页。
最佳解决方案:如果我将我的代码作为子查询按顺序排列,我可以return正确的活动记录关系。
SELECT products.*
FROM products
ORDER BY (case when
(select custom_fields.value_text
from custom_fields
where custom_fields.custom_field_definition_id = 4
and custom_fields.table_record_id = products.id and custom_fields.belongs_to_table = 'product') is null
then 'stopped'
when
(select custom_fields.value_text
from custom_fields
where custom_fields.custom_field_definition_id = 4
and custom_fields.table_record_id = products.id and custom_fields.belongs_to_table = 'product') is not null
then (select custom_fields.value_text from custom_fields where custom_fields.custom_field_definition_id = 4
and custom_fields.table_record_id = products.id and custom_fields.belongs_to_table = 'product')
end )
我不知道你在使用其他工具时遇到了什么问题 and/or Active Record 但下面的查询应该是等效的并且可能更快:
select p.*, coalesce(cf.value_text, stopped) as sorted
from
products p
left outer join custom_fields cf
on cf.table_record_id = p.id
and cf.belongs_to_table = 'product'
and cf.custom_field_definition_id = 4
order by sorted
此类查询是尽可能避免此类 "custom fields" 表的原因之一。
另一种与您的原始方法非常接近的替代方法是在 coalesce
中使用标量子查询。您甚至可能更喜欢这种方式,因为如果子查询有某种方式 return 多个值,它会导致错误。
select
p.*,
coalesce(
(
select custom_fields.value_text
from custom_fields cf
where
f.table_record_id = p.id
and cf.custom_fields.belongs_to_table = 'product'
and cf.custom_field_definition_id = 4
),
'stopped'
) as sorted
from products p
order by sorted