使用 ActiveRecord 在表上自连接
我有一个名为 Name
的 ActiveRecord,其中包含各种 Languages
的名称。
class Name < ActiveRecord::Base
belongs_to :language
class Language < ActiveRecord::Base
has_many :names
查找一种语言的名称非常容易:
Language.find(1).names.find(whatever)
但我需要找到语言 1 和语言 2 具有相同名称的匹配对。在 SQL 中,这需要一个简单的自连接:
SELECT n1.id,n2.id FROM names AS n1, names AS n2
WHERE n1.language_id=1 AND n2.language_id=2
AND n1.normalized=n2.normalized AND n1.id != n2.id;
如何使用 ActiveRecord 执行这样的查询?请注意,我需要找到成对的名称(= 匹配的双方),而不仅仅是恰好与某些内容匹配的语言 1 中的名称列表。
对于奖励积分,请将 n1.normalized=n2.normalized
替换为 n1.normalized LIKE n2.normalized
,因为该字段可能包含 SQL 通配符。
我也愿意接受以不同方式对数据进行建模的想法,但如果可以的话,我宁愿避免为每种语言使用单独的表。
I have an ActiveRecord called Name
which contains names in various Languages
.
class Name < ActiveRecord::Base
belongs_to :language
class Language < ActiveRecord::Base
has_many :names
Finding names in one language is easy enough:
Language.find(1).names.find(whatever)
But I need to find matching pairs where both language 1 and language 2 have the same name. In SQL, this calls for a simple self-join:
SELECT n1.id,n2.id FROM names AS n1, names AS n2
WHERE n1.language_id=1 AND n2.language_id=2
AND n1.normalized=n2.normalized AND n1.id != n2.id;
How can I do a query like this with ActiveRecord? Note that I need to find pairs of names (= both sides of the match), not just a list of names in language 1 that happens to match with something.
For bonus points, replace n1.normalized=n2.normalized
with n1.normalized LIKE n2.normalized
, since the field may contain SQL wildcards.
I'm also open to ideas about modeling the data differently, but I'd prefer to avoid having separate tables for each language if I can.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
试试这个:
PS:确保清理传递给连接条件的参数。
Try this:
PS: Make sure you sanitize the parameters passed to the join condition.
听起来您可能想在 Language 和 Name 之间使用多对多关系,而不是 has_many/belongs_to。
这种额外的标准化水平应该会让您尝试做的事情变得更容易。
It sounds like you might want to use a many-to-many relationship between Language and Name instead of has_many/belongs_to.
This extra level of normalization should make what you are trying to do easier.