我患有严重的肠胀气。
保持简单,我有3个表:订单,状态, XrefOrdersStatuses
我已经设置了一个带有简化模式和一些编辑行数据的SQLFiddle(SQLFiddle Here)。
我需要获得的是包含最新XrefOrdersStatuses的订单(与状态一起加入)。我可以使用以下查询来执行此操作:
SELECT o.shopper_name_first, o.shopper_name_last, os.os_name, x.xos_order_id, x.xos_status_id, x.xos_datetime
FROM Orders AS o
INNER JOIN XrefOrdersStatuses AS x ON x.xos_order_id = o.order_id
LEFT JOIN Statuses AS os ON os.os_id = x.xos_status_id
ORDER BY x.xos_order_id, x.xos_datetime DESC
结果如下:
| shopper_name_first | shopper_name_last | os_name | xos_order_id | xos_status_id | xos_datetime |
|--------------------|-------------------|---------------------|--------------|---------------|------------------------|
| Sally | Sue | Order Pre-Processed | 34049 | 31 | June, 18 2015 12:42:50 |
| Sally | Sue | Order Paid | 34049 | 20 | June, 18 2015 12:36:30 |
| Sally | Sue | Order Created | 34049 | 10 | June, 18 2015 12:34:56 |
| Joe | Schmoe | Order Pre-Processed | 34050 | 31 | June, 18 2015 12:54:50 |
| Joe | Schmoe | Order Paid | 34050 | 20 | June, 18 2015 12:38:30 |
| Joe | Schmoe | Order Created | 34050 | 10 | June, 18 2015 12:34:56 |
| Peter | Piper | Order Paid | 34051 | 20 | June, 18 2015 12:37:30 |
| Peter | Piper | Order Created | 34051 | 10 | June, 18 2015 12:34:56 |
在生产场景中,我 SELECT (更多)/所有Orders表列,为了简单起见,将它们留在这里。请注意重复的订单,但状态排列。
在视图中,我正在努力的目的不是找到最新的状态。此视图列出了订单,我希望根据最大日期时间列值加入/匹配每个订单及其各自的最新状态。一对多架构(一个订单有很多状态)。
所以我想做的是:
订单必须保留在查询中的左侧表(对于与其他表一起使用的其他连接)。在经历了许多其他SO问题和答案以及许多谷歌搜索后,我还没有找到我需要的东西。
如果需要按照最大日期时间获取XrefOrdersStatuses并按订单ID分组,这将是查询....
SELECT x.*
FROM XrefOrdersStatuses AS x
JOIN (
SELECT xos_order_id, MAX(xos_datetime) AS maxdate
FROM XrefOrdersStatuses
GROUP BY xos_order_id
) AS x1 ON x1.xos_order_id = x.xos_order_id AND x1.maxdate = x.xos_datetime;
导致:
| xos_id | xos_order_id | xos_status_id | xos_datetime |
|--------|--------------|---------------|------------------------|
| 118287 | 34051 | 20 | June, 18 2015 12:37:30 |
| 118289 | 34049 | 31 | June, 18 2015 12:42:50 |
| 118290 | 34050 | 31 | June, 18 2015 12:54:50 |
......耶!每个订单的最新状态!
唉,我需要Orders表作为左侧表(其他连接和搜索位置 - 即名称,活动/非活动,分配给用户等)。
我的麻烦是将Orders查询与XrefOrdersStatuses查询相结合。我似乎无法让他们一起玩。我的尝试因订购,分组和各种激烈的混乱而失败。
我觉得这让我很接近,但是让分组和订购正确是我在讨人喜欢的地方:
SELECT o.shopper_name_first, o.shopper_name_last, os.os_name, x.xos_order_id, x.xos_status_id, x.xos_datetime
FROM Orders AS o
JOIN (
SELECT xz.*
FROM XrefOrdersStatuses AS xz
JOIN (
SELECT xos_order_id, MAX(xos_datetime) AS maxdate
FROM XrefOrdersStatuses
GROUP BY xos_order_id
) AS x1 ON x1.xos_order_id = xz.xos_order_id AND x1.maxdate = xz.xos_datetime
) AS x
LEFT JOIN Statuses AS os ON os.os_id = x.xos_status_id
ORDER BY x.xos_order_id, x.xos_datetime DESC;
结果如下所示:
| shopper_name_first | shopper_name_last | os_name | xos_order_id | xos_status_id | xos_datetime |
|--------------------|-------------------|---------------------|--------------|---------------|------------------------|
| Joe | Schmoe | Order Pre-Processed | 34049 | 31 | June, 18 2015 12:42:50 |
| Peter | Piper | Order Pre-Processed | 34049 | 31 | June, 18 2015 12:42:50 |
| Sally | Sue | Order Pre-Processed | 34049 | 31 | June, 18 2015 12:42:50 |
| Joe | Schmoe | Order Pre-Processed | 34050 | 31 | June, 18 2015 12:54:50 |
| Peter | Piper | Order Pre-Processed | 34050 | 31 | June, 18 2015 12:54:50 |
| Sally | Sue | Order Pre-Processed | 34050 | 31 | June, 18 2015 12:54:50 |
| Peter | Piper | Order Paid | 34051 | 20 | June, 18 2015 12:37:30 |
| Sally | Sue | Order Paid | 34051 | 20 | June, 18 2015 12:37:30 |
| Joe | Schmoe | Order Paid | 34051 | 20 | June, 18 2015 12:37:30 |
我尝试了不同的变化,尝试向前,向后,向左,向右,向内,向外,向上,向下,热,冷,湿,干......你得到了图片。
我需要的是它看起来像这样:
| shopper_name_first | shopper_name_last | os_name | xos_order_id | xos_status_id | xos_datetime |
|--------------------|-------------------|---------------------|--------------|---------------|------------------------|
| Sally | Sue | Order Pre-Processed | 34049 | 31 | June, 18 2015 12:42:50 |
| Joe | Schmoe | Order Pre-Processed | 34050 | 31 | June, 18 2015 12:54:50 |
| Peter | Piper | Order Paid | 34051 | 20 | June, 18 2015 12:37:30 |
如果您回到第一个查询...我需要这些结果,但会减少,以便只保留每个订单的最新状态。我实际上是在PHP之后执行此操作...因此我正在重新查询查询以从PHP中删除看似不必要的步骤。
也许我的解决方案是XrefOrdersStatuses查询(上面的第二个),但使用RIGHT JOIN来获取Order和Status表?
有人想到吗?很抱歉让这么久(几乎TL;我自己的DR),但我希望我已经适当地注释了这个问题。
BTW - 我是SO的长期潜伏者(从这里发现的问题中收集了无数的问题和提示!)但这是我第一次陷入困境并且无法弄清楚如何获得我需要什么。编辑/解答:按照我需要的方式设置查询,发现我的性能问题与列和索引相关。有点像去医院腹痛,只是被告知你有Crohns,然后发现你的肾脏有肿瘤 - 最后事情变得很好。
# Query for answer to user Linoff with mods
SELECT o.shopper_name_first, o.shopper_name_last, s.os_name, x.*
FROM Orders o
RIGHT JOIN XrefOrdersStatuses x ON x.xos_order_id = o.order_id
RIGHT JOIN
(
SELECT xos_order_id, MAX(xos_datetime) AS maxdate
FROM XrefOrdersStatuses
GROUP BY xos_order_id
) xmax ON xmax.xos_order_id = x.xos_order_id AND xmax.maxdate = x.xos_datetime
LEFT JOIN Statuses s ON s.os_id = x.xos_status_id
ORDER BY o.order_datetime DESC;
答案 0 :(得分:0)
这是你在找什么?
SELECT <choose your columns here>
FROM Orders o LEFT JOIN
XrefOrdersStatuses x
ON x.xos_order_id = o.order_id LEFT JOIN
(SELECT xos_order_id, MAX(xos_datetime) AS maxdate
FROM XrefOrdersStatuses
GROUP BY xos_order_id
) xmax
ON xmax.xos_order_id = x.xos_order_id AND
xmax.maxdate = x.xos_datetime;
只有在没有状态记录的订单时才需要LEFT JOIN
。