Mysql 不使用订单的嵌套联接的更新
长期读者,第一次海报。我做了一些深入的搜索,但找不到任何类似的东西-提前谢谢你 我正在使用ruby和active record编写一个项目,我遇到了一个无法通过谷歌搜索两件事发生原因的情况。据我所知,第一件事是由于rails的一个已知错误而发生的。第二,我不知道 下面是模拟代码:Mysql 不使用订单的嵌套联接的更新,mysql,ruby-on-rails,activerecord,Mysql,Ruby On Rails,Activerecord,长期读者,第一次海报。我做了一些深入的搜索,但找不到任何类似的东西-提前谢谢你 我正在使用ruby和active record编写一个项目,我遇到了一个无法通过谷歌搜索两件事发生原因的情况。据我所知,第一件事是由于rails的一个已知错误而发生的。第二,我不知道 下面是模拟代码: class Object1 < ActiveRecord::Base has_many :object2s, foreign_key: :object1_id, :dependent => :delet
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
索引在更新时被绊倒,而上面没有添加**命令,日期的更新方式会导致冲突。在代码的其他地方,我已经指定了更新顺序,它将以一种不会违反索引的方式更新它们。对于此对象,加入联接会导致第一个问题:
以下是生成的模拟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:
订单被添加到错误的位置。我该如何做对,或者如何解决它
我相信这与这个bug有关:
问题2:
为什么会这样。。。从“从表中选择id”\uuuu temp\u表中选择id
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
)
这样做不是更好吗:…从表中选择id
WHERE object2.id IN (
SELECT object2.id FROM object2 INNER JOIN object1 ON object1.id = object2.object1_id WHERE <criteria>
)
当临时表已经只获取id时,是否不再需要临时表来获取id
谢谢 我真的不明白为什么顺序如此重要,只是简单地加上
LIMIT 18446744073709551615
在你的命令后面
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
)
我不知道在活动记录代码块中可以有整个活动记录代码块 这解决了这两个问题。代码:
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
1.您只更新Object2中的对象,对吗??所以你不需要任何对象2的连接。更新中的Order子句是无用的..where子句已从生成的SQL代码块中忽略,很抱歉,但您可以在更新代码块中看到它。它正在尝试更新属于Object1的所有Object2。由于索引,顺序很重要。如果数据是[[jan,1],[feb,3]],我需要将月份向前移动一个月,首先更新jan记录将使2个月变为2个月,就像我首先更新feb记录一样,它变为3月,因此当我做jan记录时,索引允许它。在activerecord代码中,我应该在哪里设置限制?上面的SQL是由服务器生成的,不是我输入的。对不起,我以为你知道ruby代码只是简单地添加了。limit18446744073709551615,就像在更新的回答中一样。如果我添加了。limit18446744073709551615,代码仍会引发错误:ActiveRecord::RecordNotUnique in CodeControllerdatechangeNew generated SQL UPDATE object2 SET obj2_date=date_subobj2_date,间隔1个月,其中object1.id=object2.object1.id=object2.object1\U id其中object1.id=15 ORDER BY object2.ObjJ2\U date ASC LIMIT 18446744073709551615\U active\U record\U temp您的问题是只需要不同的id,似乎您的内部连接过程加倍或更多ID,因此您必须使ID唯一
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)")
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