MS Access внешнее объединение нескольких полей в одну запись - PullRequest
2 голосов
/ 04 августа 2011

Мне нужно сделать то же самое, что показано здесь: ВНУТРЕННЯЯ или ЛЕВАЯ, соединяющая записи нескольких таблиц в одну строку , но она должна работать в запросе MS Access.

Ниже приведен сценарий:


Телефонный стол

+----------------+-------------+
| Field          | Type        |
+----------------+-------------+
| f_id           | int(15)     |
| f_client_id    | int(11)     |
| f_phone_type   | varchar(50) |
| f_phone_number | varchar(13) |
+----------------+-------------+

Таблица клиентов

+-----------------------------+--------------+------+-----+
| Field                       | Type         | Null | Key |
+-----------------------------+--------------+------+-----+
| f_id                        | int(15)      | NO   | PRI |
| f_first_name                | varchar(13)  | YES  | MUL |
| f_mi                        | char(1)      | YES  |     |
| f_last_name                 | varchar(20)  | NO   | MUL |
+-----------------------------+--------------+------+-----+

При стандартном соединении LEFT или INNER я получаю что-то вроде этого:

+------------+------------+--------------+
| name       | Phone Type | Phone Number |
+------------+------------+--------------+
| John Smith | Home       | 712-555-6987 |
| John Smith | Work       | 712-555-1236 |
+------------+------------+--------------+

Мне нужен запрос, который даст мне рабочие и домашние номера, которыепринадлежат данному клиенту:

+------------+----------------+--------------+
| Name       | Work Number    | Home Number  |
+------------+----------------+--------------+
| John Smith | 712-555-1236   | 712-555-6987 |
+------------+----------------+--------------+

Решение в SQL было

SELECT CONCAT(c.f_first_name, ' ', c.f_last_name) as Client_Name, 
       wp.f_phone_number as Work_Number,
       hp.f_phone_number as Home_Number

  FROM clients c
       LEFT OUTER JOIN phone hp
       ON hp.f_client_id = c.f_id
    AND
       hp.phone_type = 'home'
       LEFT OUTER JOIN phone wp
       ON wp.f_client_id = c.f_id
    AND
       wp.phone_type = 'work'

Это, однако, не переводится вMS Access, соединение не удается.Каков наилучший способ сделать то же самое с помощью Access?

Ответы [ 2 ]

5 голосов
/ 04 августа 2011

Есть две проблемы, которые вы еще не обнаружили.

  1. в Access или в его движке базы данных нет функции CONCAT ()
  2. ваш запрос пытается использовать phone_type, нофактическое имя поля: f_phone_type

При объединении более двух таблиц ядру базы данных Access требуются скобки.Проще всего сделать это правильно, используя конструктор запросов для настройки объединений.Также разработчик запросов заменит LEFT JOIN на LEFT OUTER JOIN;В Access 2003 у меня работает любой из этих способов.

Этот способ легко встроить в конструктор запросов, но он возвращает строки только для клиентов, у которых есть домашний и рабочий номера.Я использовал его в качестве отправной точки, а затем скорректировал предложения ON, аналогичные исходным.

SELECT
    c.f_first_name & " " & c.f_last_name AS [Name],
    wp.f_phone_number AS [Work Number],
    hp.f_phone_number AS [Home Number]
FROM
    (Clients AS c
    LEFT JOIN Phones AS hp
    ON c.f_id = hp.f_client_id)
    LEFT JOIN Phones AS wp
    ON c.f_id = wp.f_client_id
WHERE
    hp.f_phone_type='Home'
    AND wp.f_phone_type='Work';

Перемещение этих условий WHERE в выражения ON, как в примере с SQL Server, возвратит всех клиентов независимо от того,у вас нет телефонных номеров в файле для них.Однако такой подход потребует скобок вокруг выражений ON.И эти СОЕДИНЕНИЯ не могут отображаться в конструкторе запросов.

SELECT
    c.f_first_name & " " & c.f_last_name AS [Name],
    wp.f_phone_number AS [Work Number],
    hp.f_phone_number AS [Home Number]
FROM
    (Clients AS c
    LEFT JOIN Phones AS hp
    ON (c.f_id = hp.f_client_id AND hp.f_phone_type='Home'))
    LEFT JOIN Phones AS wp
    ON (c.f_id = wp.f_client_id AND wp.f_phone_type='Work');

Обновление : Для себя я бы предпочел сделать это с подзапросами.

SELECT
    c.f_first_name & " " & c.f_last_name AS [Name],
    wp.f_phone_number AS [Work Number],
    hp.f_phone_number AS [Home Number]
FROM
    (Clients AS c
    LEFT JOIN [
        SELECT f_client_id, f_phone_number
        FROM Phones
        WHERE f_phone_type='Home'
    ]. AS hp
    ON c.f_id = hp.f_client_id)
    LEFT JOIN [
        SELECT f_client_id, f_phone_number
        FROM Phones
        WHERE f_phone_type='Work'
    ]. AS wp
    ON c.f_id = wp.f_client_id;
0 голосов
/ 04 августа 2011

Вы также можете использовать подзапрос, например:

SELECT (firstname & " " & lastname ) AS fullname,
  (SELECT f_PhoneNumber FROM tblPhones 
   WHERE  f_clientID = clients.id AND f_PhoneType = "Home")
   AS HomeNumber,
  (SELECT f_PhoneNumber FROM tblPhones 
   WHERE  f_clientID = clients.id AND f_PhoneType = "Work")
   AS WorkNumber
FROM clients
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...