2013-03-04 41 views
3

我有一個問題,我已經搜索並找不到可以提供任何幫助的答案。MySQL - 加入最後一行相關表

有3個表格:orders,customersteams。每個訂單都有一個客戶和一個團隊。我的問題是,對於每個客戶,我試圖得到他們的總訂單,然後被分配到他們最後一個訂單的團隊。

我的查詢到目前爲止(正常工作):

SELECT c.id, MAX(o.timestamp) AS "Last Order", COUNT(o.id) AS "Total Orders", SUM(o.price) AS "Total Spend" 
FROM orders o 
LEFT JOIN customers c ON o.customer = c.id 
WHERE o.timestamp > '2012-01-01 00:00:00' 
GROUP BY c.id 
ORDER BY c.id 

我無法弄清楚如何加入team.name他們放置在最後一個順序,而不會影響我有查詢的其餘部分。

示例表和期望的結果:

客戶:

╔════╦═════════════╗ 
║ ID ║ NAME  ║ 
╠════╬═════════════╣ 
║ 1 ║ John Smith ║ 
║ 2 ║ Jim Jimmers ║ 
╚════╩═════════════╝ 

團隊:

╔════╦═════════════╗ 
║ ID ║ NAME  ║ 
╠════╬═════════════╣ 
║ 1 ║ Red   ║ 
║ 2 ║ Blue  ║ 
╚════╩═════════════╝ 

訂單:

╔═══════╦═════════════════════╦══════════╦══════╦═══════╗ 
║ ID ║  TIMESTAMP  ║ CUSTOMER ║ TEAM ║ VALUE ║ 
╠═══════╬═════════════════════╬══════════╬══════╬═══════╣ 
║ 34656 ║ 2012-03-04 14:23:44 ║  1 ║ 2 ║ 20 ║ 
║ 37345 ║ 2012-04-12 11:32:07 ║  2 ║ 2 ║ 25 ║ 
║ 38220 ║ 2012-07-18 09:53:54 ║  1 ║ 2 ║ 15 ║ 
║ 39496 ║ 2012-07-03 10:11:32 ║  1 ║ 1 ║ 38 ║ 
║ 41752 ║ 2012-09-17 19:34:05 ║  1 ║ 2 ║  9 ║ 
║ 43734 ║ 2012-11-23 07:52:12 ║  2 ║ 1 ║ 20 ║ 
╚═══════╩═════════════════════╩══════════╩══════╩═══════╝ 

如何選擇的結果,如:

╔════╦═════════════╦═════════════════════╦═══════════╦══════════════╦═════════════╗ 
║ ID ║ NAME  ║  LAST_ORDER  ║ TEAM_NAME ║ TOTAL_ORDERS ║ TOTAL_SPEND ║ 
╠════╬═════════════╬═════════════════════╬═══════════╬══════════════╬═════════════╣ 
║ 1 ║ John Smith ║ 2012-09-17 19:34:05 ║ Blue  ║   4 ║   82 ║ 
║ 2 ║ Jim Jimmers ║ 2012-11-23 07:52:12 ║ Red  ║   2 ║   45 ║ 
╚════╩═════════════╩═════════════════════╩═══════════╩══════════════╩═════════════╝ 
+0

你能給與期望的結果樣本的記錄,就像你做你以前的問題是什麼? ':)' – 2013-03-04 14:58:04

+1

您需要從團隊表中選擇多少個字段?如果這只是一個字段,那麼簡單的相關查詢就可以做到。 – Bulat 2013-03-04 15:02:55

+0

@JW。當然可以! @Bulat我只需要分配給客戶最後訂單的團隊的名稱 – BadHorsie 2013-03-04 15:13:52

回答

1

我喜歡做這個用group_concat招:

SELECT c.id, MAX(o.timestamp) AS "Last, Order", COUNT(o.id) AS "Total Orders", 
     SUM(o.price) AS "Total Spend", 
     substring_index(group_concat(teamname order by o.timestamp desc), ',', 1) as LastTeam 
FROM orders o left outer join 
    customers c ON o.customer = c.id left outer join 
    teams t 
    on o.teamid = t.id 
WHERE o.timestamp > '2012-01-01 00:00:00' 
GROUP BY c.id 
ORDER BY c.id 
+0

謝謝,我'我們來看看。順便說一句,你在'substring_index'處有一個錯字,並且在「Total Spend」(我無法編輯它;太短)後錯過了逗號。 – BadHorsie 2013-03-04 14:57:47

+0

這似乎沒有給我從他們的最後一個訂單的團隊。也許是其他命令之一,但不是符合查詢條件的最後一個命令。 – BadHorsie 2013-03-04 15:24:26

+0

這個解決方案的語法可能不正確,但這個概念是避免SUB-SELECT的最好原因!謝謝! – Thomas 2014-10-08 15:18:41

0

試試這個,

SELECT a.ID, 
     a.Name Customer_Name, 
     c.TimeStamp Last_ORDER, 
     c.Name AS Team_Name, 
     COUNT(b.Customer) AS Total_Order, 
     SUM(b.Value) AS Total_Spend 
FROM Customers a 
     INNER JOIN Orders b 
      ON a.ID = b.Customer 
     INNER JOIN 
     (
      SELECT o.Customer, 
        o.TimeStamp, 
        q.Name 
      FROM Orders o 
        INNER JOIN 
        (
         SELECT Customer, MAX(ID) max_ID 
         FROM Orders 
         GROUP BY Customer 
        ) p ON o.Customer = p.Customer AND 
          o.ID = p.max_ID 
        INNER JOIN Team q 
         ON o.Team = q.ID 
     ) c ON a.ID = c.Customer 
GROUP BY a.ID, a.Name 
+0

謝謝,我現在正在嘗試。我需要爲主要查詢添加一些條件,以確保我只選擇自2012年1月1日以來訂購的客戶。我曾嘗試添加'WHERE b.timestamp>'2012-01-01 00:00:00''最後一個「GROUP BY」,但它似乎並沒有工作,因爲我得到了大約一半的總行數,我以前。 – BadHorsie 2013-03-04 15:40:12

+0

好的,你需要在最內層查詢[SQLFiddle Demo(點擊此處)](http://www.sqlfiddle.com/#!2/8e87b/8)上添加條件,這裏是查詢日期之間的查詢,例如。 'TIMESTAMP BETWEEN'2012-01-01 00:00:00'和'2012-09-30 00:00:00'' [SQLFiddle Demo(點擊此處)](http://www.sqlfiddle.com/#! 2/8e87b/9) – 2013-03-04 15:50:31

+0

看到我更新的答案。 – 2013-03-04 15:51:46

2

您可以使用類似這樣的查詢:

select c.id, 
    c.name, 
    o1.Last_Order, 
    t.name Team_Name, 
    o3.Total_Orders, 
    o3.Total_Spend 
from customers c 
inner join 
(
    select max(timestamp) Last_Order, 
    max(id) Last_id, 
    customer 
    from orders 
    WHERE timestamp > '2012-01-01 00:00:00' 
    group by customer 
) o1 
    on c.id = o1.customer 
inner join orders o2 
    on c.id = o2.customer 
    and o1.Last_Order = o2.timestamp 
    and o1.Last_id = o2.id 
inner join teams t 
    on o2.team = t.id 
inner join 
(
    select count(team) Total_Orders, 
    sum(value) Total_Spend, 
    customer 
    from orders 
    WHERE timestamp > '2012-01-01 00:00:00' 
    group by customer 
) o3 
    on c.id = o3.customer 
WHERE o2.timestamp > '2012-01-01 00:00:00' 

SQL Fiddle with Demo

+0

感謝bluefeet,但與JW's一樣,當與我原來的帖子中的查詢進行比較時,我仍然使用此查詢返回的行數減少了約40%。 – BadHorsie 2013-03-04 16:54:51

+0

@BadHorsie你可以擴展你的數據樣本,甚至用更多的數據編輯sql小提琴嗎? – Taryn 2013-03-04 16:55:45