Другие языки программирования и технологии

SQL запросы к внешним ключам

Доброе утро! Не могу сообразить, нужна помощь! Есть, к примеру (тривиальная задача), две таблицы: "объекты" (на которых устанавливается некое оборудование), и таблица "сотрудники". За каждым объектом закреплены определенные сотрудники: ответственный, что проводил монтаж; ответственный за тех. обслуживание; менеджер. Не могу сообразить как сформировать один запрос, чтобы получить информацию о всех закрепленных сотрудниках. Есть таблицы:

Objects:
|-------------------------------------------------------------------------|
| Obj_id | Name | Manager_id | PersInst_id | PersTO_id |
|----------|-------------|----------------|----------------|---------------|
| 1 | Первый | 1 | 2 | 3 |
| 2 | Второй | 4 | 2 | 2 |
| 3 | Третий | 1 | 3 | 3 |
|-------------------------------------------------------------------------|

Persons:

|------------------------------|
| Person_id | Name |
|---------------|--------------|
| 1 | Иванов |
| 2 | Петров |
| 3 | Сидоров |
| 4 | Попов |
|------------------------------|

PS: Сорри за кривизну линий - хотел показать наглядно

Так вот, для чтения информацию по одному ответственному, делаю так:

SELECT persons.name FROM objects,persons WHERE objects.manager_id=persons.person_id AND objects.obj_id=1

Как сформировать запрос, чтобы прочитать информацию по всех трех ответственных

Тип СУБД: Firebird 2.5

Спасибо за помощь!
Выбрать все объекты и закрепленных за ними сотрудников
SELECT O.*, P.NAME FROM OBJECTS O
LEFT JOIN PERSONS P ON P.PERSONS_ID = O.MANAGER_ID

Выбрать 1 объект по его ID (= 1 первый)
SELECT O.*, P.NAME FROM OBJECTS O
LEFT JOIN PERSONS P ON P.PERSONS_ID = O.MANAGER_ID
WHERE O.OBJ_ID = 1

Выбрать только закрепленных сотрудников без объектов
SELECT DISTINCT O.MANAGER_ID, P.NAME FROM OBJECTS O
LEFT JOIN PERSONS P ON P.PERSONS_ID = O.MANAGER_ID

У Вас за каждым объектом закреплен один единственный сотрудник, Вам просто таблицы по левому краю склеить надо по таблице OBJECTS, к которой присоединится PERSONS для выбора имени сотрудника.
Из таблицы OBJECTS будут выбраны все записи, из таблицы PERSONS только те записи которые имеют ключ в таблице OBJECTS.
Диас Асанов
Диас Асанов
8 068
Лучший ответ
Алмаз Тойбулдинов Почему один если три?

А как сформировать запрос для получения информации о троих ответственных?

Спасибо!
Тривиальной задача была бы, если бы вместо полей Manager_id, PersInst_id, PersTO_id была бы одна вспомогательная таблица с 3 полями: Obj_id, Person_id, Role. У тебя же типичная связь многие-ко-многим, но с указанием роли сотрудника в каждой связи (или сразу множества ролей - если в FireBird есть аналог MySQL-типа SET; записей будет меньше, но и гибкость такого варианта будет ниже).

Если надо выбрать сотрудников в один столбец без дублей, то придётся делать UNION. На знаю, как в FireBird, а в MySQL это делается так:

(SELECT persons.name
FROM objects
INNER JOIN persons
ON persons.person_id = objects.manager_id
WHERE objects.obj_id = 1)
UNION
(SELECT persons.name
FROM objects
INNER JOIN persons
ON persons.person_id = objects.persinst_id
WHERE objects.obj_id = 1)
UNION
(SELECT persons.name
FROM objects
INNER JOIN persons
ON persons.person_id = objects.persto_id
WHERE objects.obj_id = 1)

Если же сотрудников надо выбрать в 3 столбца по ролям, то да: делается один SELECT по таблице objects с тремя JOIN к таблице persons.