我有4张桌子.
table_orders
order_id
customer_id
order_datetime
order_payment_type
order_delivery_date
delivery_time_slot
Run Code Online (Sandbox Code Playgroud)
table_order_details
order_id
product_id
varient_id
quantity
product_mrp
product_sell_price
product_name
Run Code Online (Sandbox Code Playgroud)
table_order_status
order_id
status_id
status_datetime
Run Code Online (Sandbox Code Playgroud)
table_order_status_values
value_id
value_desc
Run Code Online (Sandbox Code Playgroud)
我想获得订单ID,订单金额,订单日期,订单数量,订单时间,value_desc.
我正在运行此查询.
SELECT oo.order_id, oo.amount, oo.date, oo.quantity, oo.time, value_desc
FROM
(
SELECT s.order_id, SUM(OD.product_sell_price * OD.quantity) as amount,
DATE_FORMAT(o.order_datetime, '%d/%m/%Y') as date, SUM(OD.quantity)
as quantity, TIME(o.order_datetime) as time, MAX( status_id ) as laststatus
FROM table_orders o
INNER JOIN table_order_details AS OD ON o.order_id = OD.order_id
INNER JOIN table_order_status s ON s.order_id = o.order_id
GROUP BY o.order_id
)oo
INNER JOIN table_order_status_values ON value_id = laststatus
order by order_id DESC
Run Code Online (Sandbox Code Playgroud)
样本数据:
Table_orders
1 1 2015:12:12:19:42:47 1 2015:12:14 1
Run Code Online (Sandbox Code Playgroud)
table_order_details
1 12 3 1 21.00 20.00 abcd
1 13 2 2 100.00 90.00 efgh
Run Code Online (Sandbox Code Playgroud)
table_order_status
1 1 2015:12:12:19:42:47
1 2 2015:12:12:20:42:47
Run Code Online (Sandbox Code Playgroud)
table_order_status_values
1 NEW ORDER
2 CONFIRM
3 Delivered
Run Code Online (Sandbox Code Playgroud)
用上面的查询输出是:
1 400.00 12:12:2015 6 19:42:47 CONFIRM
Run Code Online (Sandbox Code Playgroud)
但预期产量是:
1 200.00 12:12:2015 3 19:42:47 CONFIRM
Run Code Online (Sandbox Code Playgroud)
我根据给定订单的状态数量获得订单金额和订单数量值两次(或三次).
怎么纠正这个?任何帮助将受到高度赞赏.
您应该首先将子选择的重点放在获取除状态之外的所有订单信息上,然后加入状态信息。
这可能看起来像这样:
SELECT
order_with_status.order_id AS order_id,
order_with_status.amount AS amount,
order_with_status.`date` AS `date`,
order_with_status.quantity AS quantity,
order_with_status.`time` AS `time`,
tosv.value_description AS current_status
FROM (
/* Add maximum order status value to result set */
SELECT
order.order_id AS order_id,
order.amount AS amount,
order.`date` AS `date`,
order.quantity AS quantity,
order.`time` AS `time`,
MAX(tos.status) AS current_status_id
FROM (
/* Get rolled-up order information as start to result set */
SELECT
o.order_id AS order_id,
SUM(od.product_sell_price * od.quantity) AS amount,
DATE_FORMAT(o.order_datetime, '%d/%m/%Y') AS `date`,
SUM(od.quantity) AS `quantity`,
TIME(o.order_datetime) AS `time`
FROM table_orders AS o
INNER JOIN table_order_details AS od
ON o.order_id = od.order_id
GROUP BY o.order_id
) as order
INNER JOIN table_order_status AS tos
ON order.order_id = tos.order_id
) as order_with_status
INNER JOIN table_order_status_values AS tosv
ON order_with_status.current_status_id = tosv.value_id
ORDER BY order_with_status.order_id DESC
Run Code Online (Sandbox Code Playgroud)
请注意,您的架构本身使得这是一个非常复杂的查询,如果您需要在系统中定期执行此查询,则可能无法很好地执行此查询。如果您进行简单的更改以将订单状态 id 字段移至订单表中,则可以大大简化此操作(将 table_order_status 表降级为仅作为此类查询中根本不使用的状态更改的审核历史记录)。这在逻辑上是有意义的,因为当尝试简单地获取当前订单数据时,似乎不需要处理订单的更改历史记录。
在这种情况下,查询可以像这样简单
SELECT
o.order_id AS order_id,
tosv.value_description AS current_status,
SUM(od.product_sell_price * od.quantity) AS amount,
DATE_FORMAT(o.order_datetime, '%d/%m/%Y') AS `date`,
SUM(od.quantity) AS quantity,
TIME(o.order_datetime) AS `time`
FROM table_orders AS o
INNER JOIN table_order_status_values AS tosv
ON o.order_status_id = tosv.value_id
INNER JOIN table_order_details AS od
ON o.order_id = od.order_id
GROUP BY o.order_id
ORDER BY o.order_id DESC
Run Code Online (Sandbox Code Playgroud)
如果您想将状态描述而不是 ID 放入订单表中,则可以进一步简化这一点(这将消除额外的表连接来获取描述)。
现在,这种明显的反规范化对您的应用程序是否有意义在很大程度上取决于应用程序的用例。例如,如果您访问审计数据的次数不多,或者只需要在单个订单的上下文中显示此数据,那么这可能是有意义的。