SQL - 与MAX连接(created_at)

时间:2014-12-02 22:27:58

标签: mysql sql greatest-n-per-group

问题

我有3个表:客户,公司和电话。

客户有很多公司,公司有很多电话。 (一对多)。

公司的当前状态是公司最后一次调用的结果(MAX(created_at))。

现在我想要一个客户的所有公司列表,其中包含结果中最后一次调用的列。

需要的结果

结果应该是:
company。*,lastcall。*,

  • 可能会使用相同的created_at日期进行调用。那么结果应该只有1行。
  • 并非所有公司都有呼叫,公司仍然应该在结果中,并且呼叫的列应该为NULL。 (左连接)

客户
- id(int,primary key)
- 名称(varchar)
- 地址(varchar)
- city(varchar)

公司
- id(int,primary key)
- customer_id(int)
- 名称(varchar) - 地址(varchar)
- city(varchar)

调用
- id(int,primary key)
- company_id(int)
- 结果(varchar)
- created_at(datetime)

尝试

我想出的一个不起作用的查询是:

SELECT * FROM companies co  
LEFT JOIN calls ca ON co.id = ca.company_id 
WHERE co.customer_id = ? 
GROUP BY co.id  
HAVING ca.created_at = (SELECT max(ll.created_at) FROM calls ll WHERE ll.company_id = co.id)  

5 个答案:

答案 0 :(得分:3)

你应该加入一个选择,这样你就不会试图重新评估选择。

SELECT co.id, co.label, ca.result, ca.id, t.date_created as most_recent
FROM companies co
LEFT JOIN
(   SELECT MAX(created_at) as date_created, company_id
    FROM calls
    GROUP BY company_id
) t ON t.company_id = co.id
JOIN calls ca ON ca.company_id = t.company_id AND t.date_created = ca.created_at
WHERE co.customer_id = ?

编辑:

问题是您在最长日期每个公司有多个电话。测试这个只是拉出一个客户和公司并查看结果。

SELECT co.id, co.label, ca.result, ca.id, ca.created_at as most_recent_date
FROM companies co
LEFT JOIN
(   SELECT MAX(created_at) as date_created, company_id
    FROM calls
    GROUP BY company_id
) t ON t.company_id = co.id
JOIN calls ca ON ca.company_id = t.company_id AND t.date_created = ca.created_at
WHERE co.customer_id = ? AND co.id = ?

运行此查询并指定特定公司。查看move_recent_date列,查看每行的日期是否相同,以及是否为最大日期

答案 1 :(得分:2)

您可以通过加入calls两次来完成此操作,这是第一次在子查询中检索每家公司的最后通话日期:

SELECT * FROM companies co  
LEFT JOIN (SELECT company_id, MAX(created_at) AS last_call FROM calls GROUP BY company_id) AS last_calls ON last_calls.company_id = co.id
LEFT JOIN calls ca ON ca.company_id = last_calls.company_id AND ca.created_at = last_calls.last_call
WHERE co.customer_id = ? 
GROUP BY co.id

答案 2 :(得分:1)

看起来我找到了答案。 这个给出了正确的结果,并且仍然足够快(0.27秒)

SELECT co.*, v.* 
FROM companies co 
LEFT JOIN 
( 
    SELECT 
    ca.* 
    FROM calls ca 
    JOIN 
    ( 
        SELECT 
        company_id, 
        MAX(created_at) AS max_created_at 
        FROM calls 
        GROUP BY company_id 
    ) t 
    ON ca.company_id = t.company_id AND ca.created_at = t.max_created_at
    GROUP BY company_id
) v ON co.id = v.company_id

谢谢大家!

答案 3 :(得分:0)

您可以加倍连接到lastcall表,如下例所示:

select companies.id, companies.name , lastcall.id, lastcall.result from companies
inner join (select max(created_at) as lastcall, company_id from calls group by company_id) maxcalls 
on (companies.id = maxcalls.company_id)
inner join lastcall on (lastcall = created_at and companies.id = lastcall.company_id)
where customer_id = ?


select companies.* , ca.* from companies 
inner join (select max(created_at) as lastcall, company_id from calls group by company_id) maxcalls on (companies.id = maxcalls.company_id)    
inner join calls ca on (maxcalls.lastcall = ca.created_at and companies.id = ca.company_id)
where customer_id = ?

答案 4 :(得分:0)

您应该进行子选择以从调用中获取最大值,并将其用作公司和调用表的连接条件。

SELECT
    co.id AS company_id,
    co.name AS company_name,
    ca.id AS lastcall_id,
    ca.result AS lastcall_result
FROM companies AS co
LEFT JOIN calls AS ca
    ON co.id = ca.company_id
INNER JOIN
    (
        SELECT
            company_id,
            MAX(created_at) AS max_created_at
        FROM calls
        GROUP BY company_id
    ) AS max_created_per_company
    ON ca.company_id = max_created_per_company.company_id
    AND ca.created_at = max_created_per_company.created_at
WHERE co.customer_id = ?