#sql #ms-access
#sql #ms-access
Вопрос:
Две таблицы в MS Access — клиенты и посещения — в продуктовой кладовой, где мы отслеживаем наших клиентов, когда они приходят и т.д.
Я хотел бы знать, какие клиенты раньше приходили, но в последнее время их не было; например, они пришли в pantry некоторое время в 2019 году, но с тех пор их не было.
Я получил приведенный ниже код от друга, который постоянно использует SQLPlus, но не знает Access.
Приведенный ниже код выдает мне «Синтаксическую ошибку при операции соединения». Спасибо за любую помощь в выполнении этого в Access.
SELECT tbl_Clients.[First Name], tbl_Clients.[Last Name], tbl_Visits.[Session Date]
FROM tbl_Visits
INNER JOIN
(select tbl_Visits.[Client ID], Last(tbl_Visits.[Session Date]) as LastVisit
from tbl_Visits
group by tbl_Visits.[Session Date]) V1
ON (tbl_Visits.[Client ID] = tbl_Clients.[Client ID])
WHERE LastVisit between [Start date (mm/dd/yy)] and [End date (mm/dd/yy)];
Комментарии:
1. Это не сайт разработчиков кода… покажите нам все, что вы пробовали, и задайте конкретный вопрос. нет, пожалуйста, напишите это для меня…
Ответ №1:
Вы можете использовать агрегацию:
select [Client ID], max([Session Date])
from tbl_visits
group by [Client ID]
having year(max([Session Date])) = 2019;
Если вам нужна дополнительная информация о клиентах, вы можете использовать это как подзапрос с INNER JOIN
помощью , IN
, или EXISTS
.
Комментарии:
1. Спасибо за быстрый ответ. Это дало мне по сути то, что я хотел, и я изменил НЕОБХОДИМОСТЬ в соответствии со своими спецификациями.
Ответ №2:
Ваша непосредственная ошибка заключается в ссылке на таблицу, tblClients
, в ON
предложении, которое явно не объявлено в FROM
or JOIN
. Кроме того, вы не включаете подзапрос с псевдонимом, V1
, в ON
предложение.
Кроме того, у вас есть недопустимый запрос агрегации, в котором вы GROUP BY
указываете дату сеанса (сам агрегируемый столбец), но SELECT
поле клиента. Вместо SELECT
этого и GROUP BY
поле client. Также лучше использовать MAX
, а не LAST
агрегат для дат.
В целом, рассмотрите приведенную ниже настройку, которая объединяет клиентов, посещения и подзапрос вместе, чтобы возвращать посещения каждого клиента, но только для тех клиентов, чье последнее посещение попадает в указанный диапазон времени. Затем результаты сортируются в порядке убывания по дате сеанса. Ниже используются более короткие псевдонимы таблиц.
SELECT c.[First Name]
, c.[Last Name]
, v.[Session Date]
FROM (tbl_Clients c
INNER JOIN tbl_Visits v
ON v.[Client ID] = c.[Client ID])
INNER JOIN
(SELECT sub_v.[Client ID]
, MAX(sub_v.[Session Date]) AS LastVisit
FROM tbl_Visits sub_v
GROUP BY sub_v.[Client ID]
) max_dt
ON c.[Client ID] = max_dt.[Client ID]
WHERE max_dt.LastVisit BETWEEN [Start date (mm/dd/yy)]
AND [End date (mm/dd/yy)]
ORDER BY c.[First Name], v.[Session Date] DESC;
Если вам нужна агрегация только на уровне клиента, избегайте подзапроса и агрегируйте при объединении таблиц клиентов и посещений с HAVING
фильтрацией на основе совокупного значения.
SELECT c.[First Name]
, c.[Last Name]
, MAX(v.[Session Date]) AS LastVisit
FROM tbl_Visits v
INNER JOIN tbl_Clients c
ON c.[Client ID] = v.[Client ID]
GROUP BY c.[First Name]
, c.[Last Name]
, c.[Client ID]
HAVING MAX(v.[Session Date]) BETWEEN [Start date (mm/dd/yy)]
AND [End date (mm/dd/yy)];
Комментарии:
1. Ваш код выбирает каждую строку посещений, когда мне нужно только МАКСИМАЛЬНОЕ значение. Но спасибо за быстрый и элегантный ответ.