2013-10-02 6 views
0

Мне нужно создать список активных клиентов в базе данных MS Access. Все прошлые и настоящие клиенты хранятся в таблице клиентов. Однако критерии определения активного статуса должны быть получены из двух других таблиц: прием и выход. Клиент считается активным, если у него есть дата приема, у которой нет даты выхода после нее. Однако, чтобы запутать вещи, бывший клиент, у которого есть дата выхода, может снова стать клиентом, получив новую дату приема.Фильтрация записей на основе двух других таблиц

Вот соответствующие части структуры трех таблиц, которые хранят эту информацию:

customers table 
    customerID 
    name 

intake table 
    intakeID 
    customerID 
    intakeDate 

exit date 
    exitID 
    customerID 
    exitDate 

Клиент может иметь несколько записей впускные и несколько записей выхода. Так псевдокод для утверждения SQL должен выглядеть примерно так:

SELECT customerID, name FROM customers 
WHERE ((most recent intakeDate)>(most recent exitDate(if any))) 

Что это должно выглядеть в реальной SQL? Для базы данных MS Access 2010. Очевидно, что соединения необходимы. Но какие типы объединений? И как это нужно искать?

ответ

1
SELECT ActiveCustomers.*, tblAddress.* FROM 
(
    SELECT customers.name, customers.customerID, 
    (
    SELECT COUNT(intakeDate) 
    FROM intake 
    WHERE customers.customerID = intake.customerID AND Len(intakeDate & '') > 0 
) AS IntakeCount, 
    (
    SELECT COUNT(exitDate) 
    FROM exit 
    WHERE customers.customerID = exit.customerID AND Len(exitDate & '') > 0 
) AS ExitCount 
    FROM customers 
) AS ActiveCustomers 
INNER JOIN tblAddress ON ActiveCustomers.customerID = tblAddress.customerID 
WHERE IntakeCount > ExitCount 
AND tblAddress.CurrentAddress = True 
+0

Спасибо. +1 для быстрого продуманного ответа. Вы предлагаете подсчитывать поступления и выходы, а не явно возвращать даты приема более поздней, чем любая дата выхода? Кроме того, я собираюсь создать отчет в MS Access, который извлекает данные из трех других таблиц, чтобы заполнить информацию для активных клиентов, указанных в этом запросе. Есть ли у вас общие замечания о том, как я это установлю? Могу ли я вложить еще больше SQL-операторов или просто у каждого поля в отчете будет свой собственный запрос, чтобы найти другую информацию, основанную на идентификаторе клиента, идентифицированную по его строке этим запросом? – CodeMed

+0

Вы можете, но не иметь подзапросов для других таблиц. Если вы используете вышеперечисленное, вы можете ПРИСОЕДИНЯТЬСЯ прямо к «ActiveCustomers». Например, 'FROM ActiveCustomers INNER JOIN OtherTable ON ActiveCustomers.CustomerID = OtherTable.CustomerID'. Тогда, где у меня есть 'SELECT *', вы должны указать все нужные поля. – Linger

+0

Еще раз спасибо. Дело в том, что я запутываю код ActiveCustomers. Предположим, я также хочу добавить поле с номером телефона для текущего адреса каждого активного клиента, если текущий адрес указан в одной из записей адреса клиента в таблице адресов или оставить номер телефона пустым, если адрес не указан как текущий , Где я могу добавить следующее: «INNER JOIN tblAddress ON ActiveCustomers.customerID = tblAddress.customerID ГДЕ tblAddress.CurrentAddress = -1"? Я надеюсь, что смогу собрать другие сегменты самостоятельно, увидев ваш ответ. – CodeMed

1
select * from 
    (SELECT CustomerID, Name, MAX(intakeDate) AS intakeDate, MAX(exitDate) AS exitDate 
    FROM customerstable 
    INNER JOIN intaketable 
    ON customerID = customerID 
    INNER JOIN exitdate 
    ON intaketable.customerID = exitdate.customerID 
    GROUP BY dbo.customerstable.CustomerID) c 
where intakeDate > exitDate 
+0

Спасибо. Когда я пытаюсь запустить это в доступе, он дает мне диалоговое окно, в котором говорится, что отсутствует оператор, а точка в коде, где начинается сообщение, - это userID = customerID INNER JOIN ... Любые предложения? – CodeMed

+0

Извините, эта строка должна быть: ON customerstable.customerID = intaketable.customerID – sqlgrl

+0

Спасибо. Я уже это пробовал. Мой код теперь дословный, как ваш, но доступ все еще говорит, что есть какой-то недостающий оператор. Есть запятая или что-то не хватает? – CodeMed

1

Мне нравится @ подход sqlgrl о просто глядя на последнем входе и выходе для каждого клиента, но я приспособил его использовать MS Access-определенный синтаксис, а также, я думаю, ужесточили присоединиться логику немного:

select c.* 
from ([customers table] as c 
inner join (
    select customerID, max(exitDate) as lastOut 
    from [exit date] 
    group by customerID 
) as [out] 
on c.customerID = [out].customerID) 
inner join (
    select customerID, max(intakeDate) as lastIn 
    from [intake table] 
    group by customerID 
) as [in] 
on c.customerID = [in].customerID 
where [in].lastIn > [out].lastOut 

выше в основном говорит:

  • Составьте список наиболее позднюю дату выхода каждого клиента
  • Составьте список наиболее поздней даты впускной каждого клиента
  • Присоединяйтесь два списка с таблицей клиентов
  • Если последняя дата всасываемого клиента после их последней даты выхода, включить этот клиент в конечном выходе
Смежные вопросы