Использование предложения ON для объединения таблиц с одинаковым именем столбца - PullRequest
0 голосов
/ 05 апреля 2019

Я изучаю SQL и наткнулся на следующий запрос. Я хотел спросить о состоянии предложения "ON" при объединении таблиц:

SELECT c_User.ID
FROM c_User
WHERE EXISTS (
    SELECT *
    FROM c_Group 
    JOIN c_Member ON (c_Group.Group_Name LIKE 'mcp%')
    WHERE 
        c_Group.Name = c_Member.Parent_Name
        AND c_Member.Child_Name = c_User.Lower_User_Name
)

Я знаю, что таблицы c_Member и c_Group имеют один столбец с одинаковым именем, Directory_ID. Я ожидал, что c_Member и c_Group присоединятся к этому столбцу, используя что-то вроде:

c_Group JOIN c_Member ON (c_Group.Directory_ID = c_Member.Directory_ID)
WHERE c_Group.Group_Name like 'mcp%'

Кто-нибудь объяснит, как это условие может соответствовать строкам?

c_Member ON (c_Group.Group_Name LIKE 'mcp%')
  1. Является ли это более коротким способом ссылки на две таблицы, объединяющиеся в столбце с одинаковым именем, при применении условия LIKE?
  2. Если так, то может ли такой стиль работать для таблицы с несколькими одинаковыми именами столбцов?

Любые мысли или комментарии будут с благодарностью. Спасибо за ваше время.

1 Ответ

0 голосов
/ 05 апреля 2019

Это ваш коррелированный подзапрос:

SELECT *
FROM c_Group 
JOIN c_Member ON (c_Group.Group_Name LIKE 'mcp%')
WHERE 
    c_Group.Name = c_Member.Parent_Name
    AND c_Member.Child_Name = c_User.Lower_User_Name

Этот подзапрос работает, но то, как он написан, делает его совершенно неясным:

  • Условие соединения (c_Group.Group_Name LIKE 'mcp%') на самом деле не связано с соединяемой таблицей (c_Member); что он на самом деле делает, так это применяет фильтр к таблице c_Group, что делает его фильтрацией (нет волшебства, такого как более короткий способ ссылки на две таблицы, объединяющиеся в столбце с одинаковым именем, при применении условия LIKE ). Было бы более разумно переместить его в предложение WHERE (это все равно будет функционально эквивалентно).

  • С другой стороны, предложение WHERE содержит условия, относящиеся к объединяемым таблицам (например: c_Group.Name = c_Member.Parent_Name). Более разумным вариантом было бы поместить их в предложение ON JOIN.

Другие замечания:

  • при использовании NOT EXISTS вы обычно предпочитаете SELECT 1 вместо SELECT *, (большинство СУБД оптимизирует это для вас под капотом, но это делает намерение более ясным).

  • псевдонимы таблиц могут быть использованы для того, чтобы сделать запрос более читабельным

Я бы предложил следующий синтаксис для запроса (который в основном синтаксически эквивалентен оригиналу, но намного понятнее):

SELECT u.ID
FROM c_User u
WHERE EXISTS (
    SELECT 1
    FROM c_Group g 
    JOIN c_Member m ON g.Name = m.Parent_Name AND m.Child_Name = u.Lower_User_Name
    WHERE g.Group_Name LIKE 'mcp%'
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...