嵌套连接的更新不适用于订单
Update of nested join not working with an order
好久了reader,第一次发贴。 (我做了一些深入的搜索,但找不到类似的东西——提前谢谢你)
我正在使用 ruby 和活动记录对一个项目进行编码,但我 运行 遇到无法 google 搜索为什么两件事的答案的情况发生。据我所知,第一件事是由于 rails 的一个已知错误而发生的。第二个,我不知道。
这是模拟代码:
class Object1 < ActiveRecord::Base
has_many :object2s, foreign_key: :object1_id, :dependent => :delete_all
end
class Object2 < ActiveRecord::Base
belongs_to :object1, class_name: "Object1"
end
对象 2 具有 object1_id 和日期的唯一索引。
我有一个更新因索引违规而失败:
Object1Controller 中的 ActiveRecord::RecordNotUnique#datechange
更新代码:
Object2.joins( :object1 ).where( object1: { :id => id } )**.order( obj2_date: ascdsc )**.update_all(
"obj2_date = " + direction + "(obj2_date, INTERVAL " + difference.to_s + " month)")
索引在没有顺序的更新时被触发(上面添加了**),日期的更新方式导致了违规。在代码的其他地方,我指定了更新顺序,它将以不违反索引的方式更新它们。使用此对象,添加连接会导致第一个问题:
这是生成的(模拟)SQL:
UPDATE object2 SET obj2_date = date_sub(obj2_date, INTERVAL 1 month)
WHERE object2.id IN (
SELECT id FROM (
SELECT object2.id FROM object2 INNER JOIN object1 ON object1.id = object2.object1_id WHERE <criteria> **ORDER BY object2.obj2_date ASC**
) __active_record_temp
)
如果我修改 SQL,我可以在 SQL 客户端中 运行 它,它将按预期工作。 [注:我移动了订单的位置]
UPDATE object2 SET obj2_date = date_sub(obj2_date, INTERVAL 1 month)
WHERE object2.id IN (
SELECT id FROM (
SELECT object2.id FROM object2 INNER JOIN object1 ON object1.id = object2.object1_id WHERE <criteria>
) __active_record_temp
) **ORDER BY object2.obj2_date ASC**
问题 1:
订单被添加到错误的地方。我如何正确处理或解决它?
我认为这与这个错误有关:
https://github.com/rails/rails/issues/6769
问题二:
为什么会这样? ...select id 来自 (select id 来自 table) __temp_table...
WHERE object2.id IN (
SELECT id FROM (
SELECT object2.id FROM object2 INNER JOIN object1 ON object1.id = object2.object1_id WHERE <criteria> **ORDER BY object2.obj2_date ASC**
) __active_record_temp
)
这样不是更好吗:...select id 来自 table...
WHERE object2.id IN (
SELECT object2.id FROM object2 INNER JOIN object1 ON object1.id = object2.object1_id WHERE <criteria>
)
不再需要临时 table 只是为了在已经获取 ID 的情况下获取 ID?
谢谢。
我真的不明白为什么订单如此重要,但只需添加
LIMIT 18446744073709551615
在您的 ORDER mBY 后面
UPDATE object2 SET obj2_date = date_sub(obj2_date, INTERVAL 1 month)
WHERE object2.id IN (
SELECT DISTINCT id FROM (
SELECT object2.id,object2.obj2_date FROM object2 INNER JOIN object1 ON object1.id = object2.object1_id WHERE <criteria>
) __active_record_temp
ORDER BY obj2_date ASC LIMIT 18446744073709551615
)
为什么在没有 LIMIT 的情况下忽略 order by 的原因很简单,行根据定义是无序的,因此 ORDER BY 在没有限制的情况下被删除,
Mysql 让 ORDER BY 在特殊情况下保持不变
Object2.joins( :object1 ).where( object1: { :id => id } ).order( obj2_date: ascdsc ).limit(18446744073709551615).update_all(
"obj2_date = " + direction + "(obj2_date, INTERVAL " + difference.to_s + " month)")
我不知道您可以在活动记录代码块中包含整个活动记录代码块。
这解决了这两个问题。代码:
Object2.where( id: __Object1.select( :id ).where( :parent_id => id )__ ).order( obj2_date: ascdsc ).update_all(
"obj2_date = " + direction + "(obj2_date, INTERVAL " + difference.to_s + " month)")
自动生成此 SQL:
UPDATE object2 SET obj2_date = date_add(obj2_date, INTERVAL 1 month)
WHERE object2.obj1_id IN (
SELECT object1.id FROM object1 WHERE object1.parent_id = 15
) ORDER BY object2.obj2_date ASC
好久了reader,第一次发贴。 (我做了一些深入的搜索,但找不到类似的东西——提前谢谢你)
我正在使用 ruby 和活动记录对一个项目进行编码,但我 运行 遇到无法 google 搜索为什么两件事的答案的情况发生。据我所知,第一件事是由于 rails 的一个已知错误而发生的。第二个,我不知道。
这是模拟代码:
class Object1 < ActiveRecord::Base
has_many :object2s, foreign_key: :object1_id, :dependent => :delete_all
end
class Object2 < ActiveRecord::Base
belongs_to :object1, class_name: "Object1"
end
对象 2 具有 object1_id 和日期的唯一索引。
我有一个更新因索引违规而失败:
Object1Controller 中的 ActiveRecord::RecordNotUnique#datechange
更新代码:
Object2.joins( :object1 ).where( object1: { :id => id } )**.order( obj2_date: ascdsc )**.update_all(
"obj2_date = " + direction + "(obj2_date, INTERVAL " + difference.to_s + " month)")
索引在没有顺序的更新时被触发(上面添加了**),日期的更新方式导致了违规。在代码的其他地方,我指定了更新顺序,它将以不违反索引的方式更新它们。使用此对象,添加连接会导致第一个问题:
这是生成的(模拟)SQL:
UPDATE object2 SET obj2_date = date_sub(obj2_date, INTERVAL 1 month)
WHERE object2.id IN (
SELECT id FROM (
SELECT object2.id FROM object2 INNER JOIN object1 ON object1.id = object2.object1_id WHERE <criteria> **ORDER BY object2.obj2_date ASC**
) __active_record_temp
)
如果我修改 SQL,我可以在 SQL 客户端中 运行 它,它将按预期工作。 [注:我移动了订单的位置]
UPDATE object2 SET obj2_date = date_sub(obj2_date, INTERVAL 1 month)
WHERE object2.id IN (
SELECT id FROM (
SELECT object2.id FROM object2 INNER JOIN object1 ON object1.id = object2.object1_id WHERE <criteria>
) __active_record_temp
) **ORDER BY object2.obj2_date ASC**
问题 1: 订单被添加到错误的地方。我如何正确处理或解决它?
我认为这与这个错误有关:
https://github.com/rails/rails/issues/6769
问题二: 为什么会这样? ...select id 来自 (select id 来自 table) __temp_table...
WHERE object2.id IN (
SELECT id FROM (
SELECT object2.id FROM object2 INNER JOIN object1 ON object1.id = object2.object1_id WHERE <criteria> **ORDER BY object2.obj2_date ASC**
) __active_record_temp
)
这样不是更好吗:...select id 来自 table...
WHERE object2.id IN (
SELECT object2.id FROM object2 INNER JOIN object1 ON object1.id = object2.object1_id WHERE <criteria>
)
不再需要临时 table 只是为了在已经获取 ID 的情况下获取 ID?
谢谢。
我真的不明白为什么订单如此重要,但只需添加
LIMIT 18446744073709551615
在您的 ORDER mBY 后面
UPDATE object2 SET obj2_date = date_sub(obj2_date, INTERVAL 1 month)
WHERE object2.id IN (
SELECT DISTINCT id FROM (
SELECT object2.id,object2.obj2_date FROM object2 INNER JOIN object1 ON object1.id = object2.object1_id WHERE <criteria>
) __active_record_temp
ORDER BY obj2_date ASC LIMIT 18446744073709551615
)
为什么在没有 LIMIT 的情况下忽略 order by 的原因很简单,行根据定义是无序的,因此 ORDER BY 在没有限制的情况下被删除,
Mysql 让 ORDER BY 在特殊情况下保持不变
Object2.joins( :object1 ).where( object1: { :id => id } ).order( obj2_date: ascdsc ).limit(18446744073709551615).update_all(
"obj2_date = " + direction + "(obj2_date, INTERVAL " + difference.to_s + " month)")
我不知道您可以在活动记录代码块中包含整个活动记录代码块。
这解决了这两个问题。代码:
Object2.where( id: __Object1.select( :id ).where( :parent_id => id )__ ).order( obj2_date: ascdsc ).update_all(
"obj2_date = " + direction + "(obj2_date, INTERVAL " + difference.to_s + " month)")
自动生成此 SQL:
UPDATE object2 SET obj2_date = date_add(obj2_date, INTERVAL 1 month)
WHERE object2.obj1_id IN (
SELECT object1.id FROM object1 WHERE object1.parent_id = 15
) ORDER BY object2.obj2_date ASC