2012-01-11 3 views
2

Можно ли преобразовать следующий подзапрос в 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 |    | 
+--------------+---------------------+------+-----+---------+----------------+ 
+1

Измените свой вопрос, чтобы описать схему рассматриваемых таблиц или, по крайней мере, таблицу 'user_groups'. –

+0

Я добавил обе таблицы в описание. – Simon

+1

Почему 'LEFT JOIN user_groups', а затем проверить' ug.groupstatus = 1' в предложении 'WHERE'? –

ответ

1

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

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 
+0

Да. Это прекрасно работает. Благодаря! :) – Simon

+0

Примечание: ответ Руаха также уточняет ваш запрос еще больше. Стоит прочитать его ответ, чтобы узнать, как улучшить свой запрос еще лучше, чем вы просили. – ean5533

+0

Согласен. Оба очень похожи, и оба работают, но я принял ваш, как вы отвечали в первую очередь. – Simon

2

Если предположить, что именно один 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 
; 
+0

Да, groupkey проверяет уникальность, поэтому всегда есть только одно значение. Ваш запрос тоже работает. Благодаря :) – Simon

Смежные вопросы