MySQL - 加入相关表的最后一行

时间:2013-03-04 14:48:41

标签: mysql sql

我遇到了一个我搜索过的问题,无法找到提供任何帮助的答案。

共有3个表:orderscustomersteams。每个订单都有一个客户和一个团队。我的问题是,对于每个客户,我都试图获得他们的总订单,然后分配到他们最后订单的团队。

到目前为止我的查询(工作正常):

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 ║
╚════╩═════════════╩═════════════════════╩═══════════╩══════════════╩═════════════╝

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分:1)

尝试一下,

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