Соединение слева - неизвестная ошибка столбца - PullRequest
2 голосов
/ 22 января 2012

Недавно я просматривал код своей базы данных, пытаясь улучшить свой старый код с помощью новых методов, чтобы сделать его более эффективным. Недавно я искал JOINs и обнаружил, как мне показалось, прекрасную возможность проверить это.

В настоящее время я использую следующие два запроса для формирования списка групп для пользователя:

SELECT g.group_id, g. name 
FROM assigned_groups ag, user_groups g 
WHERE ag.user_id=:user_id AND ag.group_id=g.group_id

SELECT g.group_id, g. name 
FROM users u, user_groups g 
WHERE u.user_id=:user_id AND u.base_group=g.group_id

Эти два утверждения дают мне список, но я хотел бы объединить их в одно. Единственный улов - пользователь может иметь или не иметь какие-либо группы, перечисленные в "assign_groups". То есть это необязательно.

Из того, что я понимаю, это означает, что мне нужно ЛЕВОЕ или ПРАВОЕ соединение. В настоящее время у меня есть следующий синтаксис:

SELECT g.group_id, g. name 
FROM 
  user_groups g, users u 
  LEFT JOIN assigned_groups ag ON ag.user_id=:user_id AND ag.group_id=g.group_id 
WHERE 
 u.base_group=g.group_id AND u.user_id=:user_id

Однако это дает мне следующую ошибку: Неизвестный столбец 'g.group_id' в 'предложении'

Вот изображение моей структуры таблицы: enter image description here

Ответы [ 5 ]

1 голос
/ 22 января 2012

Переход от неявного к явному JOIN

Это делает псевдоним g доступным позже в предложении FROM.

SELECT g.group_id, g.name, 
    ag.name -- guessing here
FROM 
  users u
  JOIN
  user_groups g ON u.base_group = g.group_id 
  LEFT JOIN 
  assigned_groups ag ON ag.user_id = :user_id AND ag.group_id = g.group_id 
WHERE 
  u.user_id = :user_id

Примечание: это также устраняет неоднозначность в выражении «которые присоединяются к первому»

Однако,Я думаю, ты действительно этого хочешь.Это зависит от отношения между u и ag

Правка 2, после дополнительных комментариев

SELECT g.group_id, g.name , 1 as IsBaseGroup
FROM 
  users u
  JOIN
  user_groups g ON u.base_group = g.group_id 
WHERE 
  u.user_id = :user_id
UNION
SELECT ag.group_id, ag.name, 0 as IsBaseGroup
FROM 
  users u
  JOIN 
  assigned_groups ag ON u.user_id = ag.user_id
  JOIN
  user_groups g ON ag.group_id  = g.group_id 
WHERE 
  u.user_id = :user_id;

Правка, после комментария.

SELECT 
   g.group_id, g.name, 
   CASE WHEN u.base_group = g.group_id THEN 1 ELSE 0 END AS IsBaseGroup
FROM 
  users u
  JOIN 
  assigned_groups ag ON u.user_id = ag.user_id
  JOIN
  user_groups g ON ag.group_id  = g.group_id 
WHERE 
  u.user_id = :user_id
1 голос
/ 22 января 2012

В вашем запросе вы применяете LEFT JOIN к users u слева и assigned_group ag справа.user_groups g не является частью внешнего объединения и на него нельзя ссылаться в предложении ON.

Возможно, вы имели в виду что-то вроде:

SELECT g.group_id, g.name
FROM users u,
     user_groups g LEFT JOIN assigned_groups ag
         ON ag.user_id=:user_id AND ag.group_id=g.group_id
WHERE u.base_group=g.group_id AND u.user_id=:user_id
0 голосов
/ 07 мая 2014

Попробуйте с парентезом на каждой паре столов.

Пример по вашему запросу:

SELECT g.group_id, g. name 
FROM 
  (user_groups g, users u )
  LEFT JOIN assigned_groups ag ON ag.user_id=:user_id AND ag.group_id=g.group_id 
WHERE 
 u.base_group=g.group_id AND u.user_id=:user_id

Более общий пример:

SELECT a.*, b.*, c.*, d.*
FROM 
  (
     (
       (table1 a, table2 b)
       , table3 c
     )
     LEFT JOIN table4 d ON a.id=d.id and b.idx = d.idx
  )
WHERE 
 u.base_group=g.group_id AND u.user_id=:user_id
0 голосов
/ 22 января 2012

Веселитесь вместе с ним

SELECT g.group_id, g.name
FROM groups g
LEFT JOIN assigned_groups ag 
      ON  ag.group_id=g.group_id
LEFT JOIN users u
      ON  u.base_group=g.group_id
WHERE u.user_id=:user_id OR ag.user_id=:user_id
0 голосов
/ 22 января 2012

Возможно, это поможет вам.Имя ag.name может иметь значение NULL, когда оно возвращает строки, как вы, вероятно, поняли это.Если вам это нужно, исключите поле g.name из списка выбора.

SELECT u.name,ug.name
FROM  users u 
INNER JOIN assigned_groups ag 
ON u.user_id=ag.user_id
INNER JOIN user_groups ug
ON ag.group_id=ug.group_id    
WHERE u.user_id=:user_id

Cheers

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...