如何获取所有具有共同状态的订单?
How to get orders all of which have a common status?
我有一个订单和订单项目的实施。即每个订单都有一定数量的商品。
每个订单项都有一个由枚举“控制”的状态字段。
enum status: {
opened: 0,
checked: 1,
spoiled: 2
}, _prefix: :status
你能告诉我如何只获取那些所有项目都处于“已检查”状态的订单吗?
我被困在这个:
left_outer_joins(:orders_items)
.where(
orders_items: {
status: :checked
}
)
.where(orders_items: { id: nil })
# OR .where.missing(:orders_items)
或者:
left_outer_joins(:orders_items)
.where(
orders_items: {
status: %i[
opened
spoiled
]
}
)
.having('COUNT(orders_items.id) = 0')
.group('orders.id')
据我了解,我需要以某种方式获得以下订单:
没有项目的状态不是“已检查”;
或
状态为“已检查”的商品数量等于订单中所有商品的数量;
或
除“已检查”之外的任何状态的项目数为零。
但是我不明白这是怎么做到的...希望得到你的帮助
有很多方法可以做到这一点。最简单的方法是 WHERE NOT IN 子查询:
Order.where.not(
id: Order.joins(:order_items)
.where.not(order_items: { status: :checked })
)
您也可以使用 NOT EXIST:
Order.where(
OrderItem.select(:id)
.where(
# order_items.version_id = orders.id
OrderItem.arel_table[:order_id].eq(Order.arel_table[:id])
)
.where.not(status: :checked)
.arel
.exists.not
)
这些都依赖于这样一个事实,即具有任何 order_item 而没有 status = 1
的订单不符合条件。如果你想要更接近段落 The number of items with the "checked" status is equal to the number of all items in the order.
的东西,你可以使用子查询:
orders, order_items = Order.arel_table, OrderItem.arel_table
subquery = OrderItem.select(order_items[:*].count)
.where(order_items[:order_id].eq(order[:id]))
Order.select(
orders[*],
subquery.arel.as('order_items_count'), # can be replaced with a counter-cache
subquery.where(status: :checked).arel.as('checked_count')
)
.where(orders[:order_items_count].eq(orders[:not_checked_count])
或聚合:
orders, order_items = Order.arel_table, OrderItem.arel_table
subquery = OrderItem.select(order_items[:*].count)
.where(order_items[:order_id].eq(order[:id]))
Order
.left_joins(:order_items)
.select(
orders[*],
subquery.where(status: :checked).arel.as('checked_count')
)
.group(:id)
.having(
order_items[:*].eq(orders[:checked_count])
)
我有一个订单和订单项目的实施。即每个订单都有一定数量的商品。
每个订单项都有一个由枚举“控制”的状态字段。
enum status: {
opened: 0,
checked: 1,
spoiled: 2
}, _prefix: :status
你能告诉我如何只获取那些所有项目都处于“已检查”状态的订单吗?
我被困在这个:
left_outer_joins(:orders_items)
.where(
orders_items: {
status: :checked
}
)
.where(orders_items: { id: nil })
# OR .where.missing(:orders_items)
或者:
left_outer_joins(:orders_items)
.where(
orders_items: {
status: %i[
opened
spoiled
]
}
)
.having('COUNT(orders_items.id) = 0')
.group('orders.id')
据我了解,我需要以某种方式获得以下订单:
没有项目的状态不是“已检查”;
或
状态为“已检查”的商品数量等于订单中所有商品的数量;
或
除“已检查”之外的任何状态的项目数为零。
但是我不明白这是怎么做到的...希望得到你的帮助
有很多方法可以做到这一点。最简单的方法是 WHERE NOT IN 子查询:
Order.where.not(
id: Order.joins(:order_items)
.where.not(order_items: { status: :checked })
)
您也可以使用 NOT EXIST:
Order.where(
OrderItem.select(:id)
.where(
# order_items.version_id = orders.id
OrderItem.arel_table[:order_id].eq(Order.arel_table[:id])
)
.where.not(status: :checked)
.arel
.exists.not
)
这些都依赖于这样一个事实,即具有任何 order_item 而没有 status = 1
的订单不符合条件。如果你想要更接近段落 The number of items with the "checked" status is equal to the number of all items in the order.
的东西,你可以使用子查询:
orders, order_items = Order.arel_table, OrderItem.arel_table
subquery = OrderItem.select(order_items[:*].count)
.where(order_items[:order_id].eq(order[:id]))
Order.select(
orders[*],
subquery.arel.as('order_items_count'), # can be replaced with a counter-cache
subquery.where(status: :checked).arel.as('checked_count')
)
.where(orders[:order_items_count].eq(orders[:not_checked_count])
或聚合:
orders, order_items = Order.arel_table, OrderItem.arel_table
subquery = OrderItem.select(order_items[:*].count)
.where(order_items[:order_id].eq(order[:id]))
Order
.left_joins(:order_items)
.select(
orders[*],
subquery.where(status: :checked).arel.as('checked_count')
)
.group(:id)
.having(
order_items[:*].eq(orders[:checked_count])
)