Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/52.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 基于关联模型数的查询_Sql_Ruby On Rails_Postgresql_Activerecord_Scopes - Fatal编程技术网

Sql 基于关联模型数的查询

Sql 基于关联模型数的查询,sql,ruby-on-rails,postgresql,activerecord,scopes,Sql,Ruby On Rails,Postgresql,Activerecord,Scopes,我正在从事一个项目,在这个项目中,我需要根据where子句下关联模型的数量来确定模型的范围。这是我能想到的最好的办法: Subscription.where('message_cap > ?', TextMessage.where('created_at > ?', DateTime.now.beginning_of_month).where(subscription: subscription).count) 但是,它不起作用,因为订阅未定义。在rails查询中,我是否可以引用p

我正在从事一个项目,在这个项目中,我需要根据where子句下关联模型的数量来确定模型的范围。这是我能想到的最好的办法:

Subscription.where('message_cap > ?', TextMessage.where('created_at > ?', DateTime.now.beginning_of_month).where(subscription: subscription).count)
但是,它不起作用,因为订阅未定义。在rails查询中,我是否可以引用postgres当前访问的模型?我想这就是我要寻找的SQL:

SELECT * FROM 'subscriptions' WHERE 'subscription.message_cap' > (SELECT COUNT(*) FROM 'text_messages' WHERE 'text_messages.subscription_id' = 'subscription.id' AND 'text_message.created_at > BEGINNINGOFMONTH')
这是我的应用程序中非常、非常关键的性能部分,因此如果可以的话,我需要在一个查询中运行它

编辑


顺便说一下,我不确定上面的SQL查询是否有效。我把它放在那里只是为了表达我所寻找的东西的想法。

尝试以下内容:

Subscription.select('subscriptions.id').
  joins(:text_messages).
  where('messages.created_at > ?', date).
  group('subscriptions.id').
  having('COUNT(*) > subscriptions.message_cap')
Subscription.find(ids)
查询的参数是
date

请注意,结果中的每个
Subscription
对象将只包含订阅的
id
。要检索完整对象,您需要进行如下查询:

Subscription.select('subscriptions.id').
  joins(:text_messages).
  where('messages.created_at > ?', date).
  group('subscriptions.id').
  having('COUNT(*) > subscriptions.message_cap')
Subscription.find(ids)
如果查询是应用程序的关键部分,则应使用您喜爱的测试框架测试查询

query = "SELECT * FROM 'subscriptions' WHERE 'subscription.message_cap' > (SELECT COUNT(*) FROM 'text_messages' WHERE 'text_messages.subscription_id' = 'subscription.id' AND 'text_message.created_at > BEGINNINGOFMONTH')"
Subscription.find_by_sql(query)
如果这还不够快,那么您应该研究缓存每个订阅的文本消息数。这可以通过创建视图或向订阅表中添加计数器列来实现。视图是更好的解决方案,但更需要实施

更新
可能使用
.select('subscriptions.*)
?问题的一部分在于计数对于每个型号也是唯一的。这就是为什么我有
消息\u cap
。它是订阅模型上的一列。订阅。*在PostgreSQL(至少)中不起作用,因为您不能选择不在group by子句中的列。@DylanKarr message\u cap代表什么?你是说每个订阅都有不同的计数限制?它是一个整数。这只是每个订阅可以接收多少条文本消息的基本限制。我不希望使用这样的查询字符串,因为我的表名将来可能会更改。另外,我不确定这个查询是否真的有效。@DylanKarr没问题,请检查更新以获得更动态的解决方案。