Преобразовать подзапрос, чтобы присоединиться - PullRequest
2 голосов
/ 11 января 2012

Можно ли преобразовать следующий подзапрос в JOIN, предпочтительно без производной таблицы?

SELECT * FROM users u
LEFT JOIN user_groups ug ON u.usergroupid=ug.groupid
WHERE
u.userstatus=1 AND
ug.groupstatus=1 AND
ug.grouprank>=(SELECT grouprank FROM user_groups WHERE groupkey='users')

Таблица user_groups выглядит следующим образом:

+-------------+---------------------+------+-----+---------+----------------+
| Field       | Type                | Null | Key | Default | Extra          |
+-------------+---------------------+------+-----+---------+----------------+
| groupid     | tinyint(3) unsigned | NO   | PRI | NULL    | auto_increment |
| groupkey    | varchar(8)          | NO   |     | NULL    |                |
| grouprank   | smallint(6)         | NO   |     | NULL    |                |
| groupstatus | tinyint(1) unsigned | NO   |     | NULL    |                |
+-------------+---------------------+------+-----+---------+----------------+

Таблица пользователей выглядит так:

+--------------+---------------------+------+-----+---------+----------------+
| Field        | Type                | Null | Key | Default | Extra          |
+--------------+---------------------+------+-----+---------+----------------+
| userid       | int(10) unsigned    | NO   | PRI | NULL    | auto_increment |
| username     | varchar(32)         | NO   |     | NULL    |                |
| userpassword | varchar(32)         | NO   |     | NULL    |                |
| usergroupid  | tinyint(3) unsigned | NO   |     | NULL    |                |
| userstatus   | tinyint(1) unsigned | NO   |     | NULL    |                |
+--------------+---------------------+------+-----+---------+----------------+

Ответы [ 2 ]

2 голосов
/ 11 января 2012

Предполагая, что ровно одна user_groups запись имеет groupkey = 'users' (поскольку в противном случае ваш запрос недействителен), ваш запрос эквивалентен следующему:

SELECT u.*,
       ug1.*
  FROM users u
  LEFT
  JOIN user_groups ug1
    ON u.usergroupid = ug1.groupid
  LEFT
  JOIN user_groups ug2
    ON ug2.groupkey = 'users' -- not a real join condition
 WHERE u.userstatus = 1
   AND ug1.groupstatus = 1
   AND ug1.grouprank >= ug2.grouprank
;

Но обратите внимание, что LEFT JOIN s фактически заканчиваютсяработать как INNER JOIN s, так как ваше предложение WHERE зависит от того, какие соединения были успешными.Так что вы, вероятно, действительно хотите что-то вроде этого:

SELECT u.*,
       ug1.*
  FROM users u
  LEFT
  JOIN user_groups ug1
    ON u.usergroupid = ug1.groupid
   AND ug1.groupstatus = 1
  LEFT
  JOIN user_groups ug2
    ON ug2.groupkey = 'users'
   AND ug1.grouprank >= ug2.grouprank
 WHERE u.userstatus = 1
;
1 голос
/ 11 января 2012

Я думаю, это то, что вы ищете - проведите тест.

SELECT * FROM users u
LEFT JOIN user_groups ug ON u.usergroupid=ug.groupid
JOIN user_groups ug2 ON ug.grouprank >= ug2.grouprank AND ug2.groupkey = 'users'
WHERE
u.userstatus=1 AND
ug.groupstatus=1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...