2015-06-18 43 views
0

我患有嚴重的腦脹氣。Mysql如何減少由max datetime和group by non-uniq id造成的行

保持簡單,我有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 | 

在生產場景中我選擇(荷蘭國際集團)以上/所有Orders表列,爲了簡單起見,這裏只是把它們留在這裏請注意重複的訂單,但狀態一致。

在視圖中,我正在處理的目的不是找到最新的狀態。此視圖列出訂單,並且我想根據最大日期時間列值將每個訂單及其各自的最新狀態加入/匹配。一對多模式(一個訂單有很多狀態)。

所以我想要做的是:

  • SELECT命令
  • JOIN與MAX(xos_datetime)集團外部參照BY xos_order_id
  • JOIN狀態得到定義

訂單必須保持查詢中的左側表格(用於與其他表格一起使用的其他連接)。在經歷了許多其他的SO問題和答案以及許多Google搜索之後,我還沒有完全找到我需要的東西。

如果需要得到公正的最大日期時間的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 | 

...耶!每個訂單的最新狀態!我需要訂單表作爲左側表(其他連接和其中的搜索 - 即名稱,活動/非活動,分配給用戶等)。

我的問題是將訂單查詢與XrefOrdersStatuses查詢組合在一起。我似乎不能讓他們一起玩。我的嘗試失敗,訂購,分組,以及各種各樣的熱浪。

我喜歡這種感覺讓我接近,但得到的分組和排序正確的是在那裏我flatulating:

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來獲取訂單和狀態表?

想到任何人?對不起,這麼長時間(差不多TL;我自己),但我希望我已經適當地註釋了這個問題。

順便說一句 - 我是一個很長時間的潛伏者(無數問題和提示已經從這裏發現的問題中搜集到!),但這是我第一次陷入困境,無法弄清楚如何得到我需要的東西。


編輯/答案:以我需要的方式得到了查詢設置,並發現我的性能問題與列和索引相關。有點像去醫院治療腹痛,只有被告知你有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

這是你在找什麼?

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

+0

它的工作原理,它不工作....我已經嘗試過這種途徑幾種不同的方式。雖然,建立一個沿着相同的道路走下去,並思考回正確的聯接,而不是... 答案可能在眼前。在IDE中測試.... – Rodney

+0

如果我們修改爲外部參考連接的RIGHT JOIN,則LEFT JOIN連接狀態,ORDER BY Orders.order_datetime它似乎在小提琴中起作用。 http://sqlfiddle.com/#!2/9ae7cc/4/0 但是當我在我的控制檯中複製時,我無法在生產數據上獲得類似的輸出。在查詢中,我的表現非常糟糕。我開始懷疑我的目標是讓查詢服務於我所需要的數據。 – Rodney

+0

@Rodney。 。 。如果你有適當的外鍵關係,我不明白爲什麼你需要混合左右連接。事實上,除了某些訂單可能沒有地位的可能性之外,您根本不需要外部連接。 –