我有3个表:客户,公司和电话。
客户有很多公司,公司有很多电话。 (一对多)。
公司的当前状态是公司最后一次调用的结果(MAX(created_at))。
现在我想要一个客户的所有公司列表,其中包含结果中最后一次调用的列。
结果应该是:
company。*,lastcall。*,
客户
- 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)
答案 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 = ?