Вопрос или проблема
Я работаю с Sybase ASE 16 и пытаюсь совместить внутреннее соединение с левым, чтобы получить соответствующие строки из первых двух таблиц, добавляя данные из третьей таблицы, если они присутствуют.
Схема:
События
id | guid | other_id | eventType | date |
---|---|---|---|---|
1 | 1234 | 5 | приветствие | 2024-10-10 |
2 | 1234 | 5 | приветствие | 2024-10-12 |
1 | 9876 | 10 | отклонить | 2024-11-09 |
2 | 9876 | 10 | отклонить | 2024-11-11 |
Контракты
id | guid | other_id | user | isHappy |
---|---|---|---|---|
1 | 2345 | 5 | Боб | 0 |
1 | 9234 | 10 | Джейн | 0 |
2 | 9234 | 10 | Джейн | 1 |
События
id | guid | взаимодействия |
---|---|---|
1 | 9876 | 1 |
2 | 9876 | 2 |
3 | 9876 | 5 |
Что я хочу получить – это события, которые произошли (или после) 2024-11-11 для конкретного eventType
, где пользователь isHappy
, а затем добавить количество взаимодействий, если они существуют (в противном случае null). Запрос должен смотреть только на высший id
на каждый guid
в каждой соответствующей таблице, хотя я не знаю, как это сделать с левым соединением с последней таблицей.
Итак, если я смотрю на eventType=отклонить
и date=2024-11-11
, я бы ожидал
id | date | other_id | isHappy | user | взаимодействия |
---|---|---|---|---|---|
2 | 2024-11-11 | 10 | 1 | Джейн | 5 |
В то время как, если я смотрю на eventType=приветствие
и date=2024-10-11
, я бы ожидал
id | date | other_id | isHappy | user | взаимодействия |
---|---|---|---|---|---|
2 | 2024-10-12 | 5 | 0 | Боб | null |
Ниже приведено то, что у меня есть, и это, по-видимому, возвращает правильное соединение между первыми двумя таблицами, но с левым соединением просто сбрасывает таблицу События
в результаты.
select e.id, e.date, e.other_id, c.isHappy, c.user, o.interactions
from Events e,
Contracts c,
Occurences o
where e.other_id=c.other_id
and e.eventType="отклонить"
and e.guid*=o.guid
group by e.guid
having e.id=max(e.id) and e.date >= '2024-11-11'
Ответ или решение
Вопрос о соединении нескольких таблиц, используя левое соединение в Sybase ASE 16, требует четкого понимания различных типов JOIN и методов обработки данных. При этом важно создать запрос, который выводит необходимые данные, учитывая условия по типу события и дате, а также предварительно отфильтровать данные по максимальному идентификатору записи.
1. Описание проблемы
В вашем запросе необходимо соединить три таблицы: Events
, Contracts
и Occurences
. Вы хотите получить события определенного типа, произошедшие после установленной даты, с дополнительной информацией о пользователе и количестве взаимодействий, если таковые имеются.
2. Решение с использованием подзапросов для выбора максимальных значений
Чтобы получить максимальные идентификаторы событий, контрактов и взаимодействий, вам нужно использовать подзапросы для фильтрации данных по максимальному id
для каждого guid
. Это позволит исключить дублирование данных и получить только последние записи.
3. Полный SQL-запрос
Для выполнения вашей задачи следует использовать следующий SQL-запрос:
SELECT
e.id,
e.date,
e.other_id,
c.isHappy,
c.user,
o.interactions
FROM
(SELECT *
FROM Events
WHERE date >= '2024-11-11' AND eventType = 'reject') AS e
JOIN
(SELECT *
FROM Contracts
WHERE id IN (SELECT MAX(id) FROM Contracts GROUP BY guid, other_id)) AS c
ON
e.other_id = c.other_id
LEFT JOIN
(SELECT *
FROM Occurences
WHERE id IN (SELECT MAX(id) FROM Occurences GROUP BY guid)) AS o
ON
e.guid = o.guid
WHERE
e.id = (SELECT MAX(id) FROM Events WHERE guid = e.guid)
ORDER BY
e.date;
4. Объяснение запроса
- Субзапросы для
Events
,Contracts
иOccurences
: каждый из этих подзапросов выбирает последние записи поguid
, что позволяет избежать повторного вывода. - Lef Join: Используется для соединения с таблицей
Occurences
, что обеспечивает наличие соответствующих данных взаимодействий, а также добавляет возможность полученияNULL
, если записи отсутствуют. - Условия фильтрации: В WHERE-клаузе задаются условия для события по дате и типу события.
5. Убедитесь, что вы на правильном пути
Проверьте, что ваши графики и условия корректно представлены в запросе, чтобы результаты соответствовали ожидаемым. Теперь, обращаясь к данным, вы сможете легко адаптировать запрос для различных типов событий или дат, просто изменяя значения в фильтрах.
Заключение
С помощью приведенного выше запроса вы сможете корректно соединить таблицы и получить желаемые данные. Важно помнить, что реализация SQL-запросов требует тщательного планирования, особенно при использовании различных видов соединений. Убедитесь, что вы тестируете и проверяете результаты, чтобы обеспечить целостность получаемых данных.