MySQL LEFT JOIN 导致 "duplicate" 行
MySQL LEFT JOIN is causing "duplicate" rows
我有表 "customers" 和 "plans",我想列出所有客户,无论他们是否有计划。我正在使用查询来做到这一点
SELECT customer.name, plan.goal
FROM customer
LEFT JOIN plan ON plan.customerid=customer.customerid
ORDER BY customer.name
我也想看看有客户名字的目标(plan.goal)。只要客户没有计划或只有一个计划,这就有效。如果客户有两个或更多计划,那么我会得到与计划一样多的客户名称行。
我要的是最新计划的customer.name和plan.goal。我们可以假设 plan.planid 中的较高值是最新计划。
我想我应该使用子查询和 INNER JOINS 一些方式,但我现在不明白...
我认为这样的方法可行:
SELECT customer.name, plan.goal
FROM customer c
inner join plan p on c.customerId = p.customerId
inner JOIN (
-- grabs the most recent plan per customer
select max(planId) as planId, customerId
from plan
group by customerId
) maxPlan on p.planId = maxPlan.planId
UNION
-- handles customers w/o a plan
select customer.name, null
from customer c
left join plan p on c.customerId = p.customerId
where p.customerId is null
ORDER BY customer.name
SELECT c.name,
( SELECT p.goal
FROM plan p
WHERE p.customerid=c.customerid
AND NOT EXISTS ( SELECT 'a'
FROM plan p2
WHERE p2.customerid = p.customerid
AND p2.planid > p.planId
)
)
FROM customer c
我认为您应该在计划 table 中添加一个 boolean/tinyint 列,上面写着 IsLatest
或类似的内容。那么你可以这样做:
SELECT customer.name, plan.goal
FROM customer
LEFT JOIN plan ON plan.customerid=customer.customerid
where testplan.islatest = 1 or testplan.islatest is null
ORDER BY customer.name
此外,我会远离子查询答案,例如
select a from (select b from c where e=f) where g=h
因为它们通常表现不佳,而且阅读起来很混乱。
我有表 "customers" 和 "plans",我想列出所有客户,无论他们是否有计划。我正在使用查询来做到这一点
SELECT customer.name, plan.goal
FROM customer
LEFT JOIN plan ON plan.customerid=customer.customerid
ORDER BY customer.name
我也想看看有客户名字的目标(plan.goal)。只要客户没有计划或只有一个计划,这就有效。如果客户有两个或更多计划,那么我会得到与计划一样多的客户名称行。
我要的是最新计划的customer.name和plan.goal。我们可以假设 plan.planid 中的较高值是最新计划。
我想我应该使用子查询和 INNER JOINS 一些方式,但我现在不明白...
我认为这样的方法可行:
SELECT customer.name, plan.goal
FROM customer c
inner join plan p on c.customerId = p.customerId
inner JOIN (
-- grabs the most recent plan per customer
select max(planId) as planId, customerId
from plan
group by customerId
) maxPlan on p.planId = maxPlan.planId
UNION
-- handles customers w/o a plan
select customer.name, null
from customer c
left join plan p on c.customerId = p.customerId
where p.customerId is null
ORDER BY customer.name
SELECT c.name,
( SELECT p.goal
FROM plan p
WHERE p.customerid=c.customerid
AND NOT EXISTS ( SELECT 'a'
FROM plan p2
WHERE p2.customerid = p.customerid
AND p2.planid > p.planId
)
)
FROM customer c
我认为您应该在计划 table 中添加一个 boolean/tinyint 列,上面写着 IsLatest
或类似的内容。那么你可以这样做:
SELECT customer.name, plan.goal
FROM customer
LEFT JOIN plan ON plan.customerid=customer.customerid
where testplan.islatest = 1 or testplan.islatest is null
ORDER BY customer.name
此外,我会远离子查询答案,例如
select a from (select b from c where e=f) where g=h
因为它们通常表现不佳,而且阅读起来很混乱。