2015-03-03 3 views
0

У меня есть таблицы «клиенты» и «планы», и я хочу перечислить всех клиентов, независимо от их плана или нет. Я использую запрос, чтобы сделать этоMySQL LEFT JOIN вызывает «повторяющиеся» строки

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 из последнего плана. Мы можем предположить более высокую ценность в плане. Планид - это последний план.

Я предполагаю, что я должен использовать подзапросы и ВНУТРЕННИЙ JOINS как некоторые, но я просто не получить его прямо сейчас ...

+0

Как вы определяете «последний план», существует ли дата-время или желательно идентификатор автоматического увеличения на столе? – Kritner

+0

plan.planid auto incremented –

+0

Вам нужно использовать несколько запросов, ваш первый абзац противоречит вашему второму и третьему. –

ответ

1

Я думаю, что что-то подобное будет работать:

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 
+0

Вышеупомянутый не является клиентом, если у клиента нет плана. –

+0

обновленный ответ, можете ли вы попробовать, чтобы попробовать? – Kritner

+0

Я сделаю это сразу –

3
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 
1

Я думаю, вы должны добавить столбец 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 

, так как они часто не выполняют очень хорошо, кроме того, что сбивает с толку читать.

+0

Это чище, и в нем перечислены все клиенты, но он не перечисляет цели из последних планов, если есть несколько планов для каждого клиента. –

+0

Ты уверен, что правильно. Виноват. Я думаю, вы должны добавить столбец в таблицу планов, в котором говорится 'isactive' или' islatest' или что-то в этом роде. Немного дополнительных данных для хранения, но это упрощает эту ситуацию, поскольку вы можете добавить это в предложение where и избегать сложных/суб/вложенных запросов. –

+0

Я отредактировал свой ответ, чтобы использовать новый подход к колонке, поскольку я думаю, что это лучшее решение. –