2017-07-31 64 views
0

很抱歉,如果这个问题是混乱的,因为我不知道如何问这样的问题,但在这里我去:从接单,所有订单的状态为选择用户“出错”

我在里面的rails控制台试图找到所有订单中所有订单状态都是“错误”的订单,并且只出现错误。用户有很多订单,每个订单的订单状态可能与“完成”,“退款”或“错误”有所不同。

User.includes(:orders).where(orders: { state: "errored" }) 

这是谁恢复有一个或多个差错订单的所有用户,因为它是猜想,用户是否拥有与其他国家的订单也是如此。但是,我试图获取只有有错误订单的用户。

我已经尝试了很多东西,从遍历每个用户的每个订单,尝试手动找到它们。但它是一个更好的方法。

回答

1

我的SQL是不是它曾经是,但我相信,对于一个纯粹的SQL解决方案就需要看起来像:

SELECT "users".* 
    FROM "users" 
    LEFT JOIN orders on orders.user_id = users.id 
    LEFT JOIN orders non_errored_orders on non_errored_orders.user_id = users.id and non_errored_orders.state <> 'errored' 
    WHERE "non_errored_orders"."id" IS NULL AND "orders"."id" IS NOT NULL 

所以,我们离开加盟orders表别名non_errored_orders并且这将使得如果存在用户ID匹配并且状态不等于错误的订单,则会出现一行(并且non_errored_orders.id将最终为NOT NULL)。在where条款中,我们接着过滤掉只有用户non_errored_orders.id IS NULL,筛选出与错误的订单匹配的所有用户出错

然后我们再次加入orders表,并且没有别名,只匹配users.id = orders.user_id。如果没有orders.id,那意味着用户在表格中根本没有任何订单,所以我们只想过滤掉只有orders.user_id IS NOT NULL的用户,这意味着他们有订单。

你可以做这样的事情做这样的查询中轨:

User. 
    joins(:orders). 
    joins("LEFT JOIN orders non_errored_orders on non_errored_orders.user_id = users.id and non_errored_orders.state <> 'errored'"). 
    where(non_errored_orders: { id: nil }). 
    where.not(orders: { id: nil }).distinct 
# User Load (0.3ms) SELECT DISTINCT "users".* FROM "users" INNER JOIN "orders" ON "orders"."user_id" = "users"."id" LEFT JOIN orders non_errored_orders on non_errored_orders.user_id = users.id and non_errored_orders.state <> 'errored' WHERE "non_errored_orders"."id" IS NULL AND ("orders"."id" IS NOT NULL) LIMIT ? [["LIMIT", 11]] 
# => #<ActiveRecord::Relation [#<User id: 1, ...>]> 

在我的非常有限的测试集,这似乎是工作。

测试数据为

User.find(1).orders.create([ { state: 'errored' }, { state: 'errored' } ]) 
User.find(2).orders.create([ { state: 'errored' }, { state: 'completed' }]) 
User.find(3).orders.create([ { state: 'refunded' } ]) 
+0

这工作完美,真正学到了新的东西在这里!非常感谢。 – Hamza1510

-1

我想你可以尝试定义一个errored_orders关系:

class User < ApplicationRecord 
    has_many errored_orders, ->{where state: 'errored'} 
end 

User.includes(:errored_orders).where(...) 

希望它能帮助!

0

如何有点长,但简化路径?

users_with_other_order_states = User.join(:orders).where.not(orders: { state: "errored" }).pluck(:id) 

User.joins(:orders).where('orders.state = "errored" AND users.id NOT IN (?)', users_with_other_order_states) 
+0

谢谢你给这个镜头。我尝试使用简化路径时遇到错误,我修复了错别字,但仍然无法正常工作。它给我这个消息:ActiveRecord :: StatementInvalid:PG :: SyntaxError:ERROR:语法错误在或接近“912” LINE 1:... ERE(orders.state =“errored”AND users.id NOT IN 912, 25,123 ... 但无论如何,下面的答案之一得到了解决方案。无论如何,谢谢你给它一个镜头。 – Hamza1510

+0

刚刚更新了解决方案。由于SQL语法错误,该错误即将到来。用'(?)'改变'?' –

相关问题