2014-07-15 4 views
1

Im пытаясь определить власти-по-имя пользователя-запрос: для Spring SecuritySQL Query возвращает слишком много данных

SELECT u.username, r.authrole FROM users u, roles r, user_role ur 
        WHERE u.id = ur.userid AND u.username = 'dit' 

Его неловкого, но этот запрос возвращает неправильный результат, и я не могу это исправить ,

Результат:

username  authrole 
----------------------- 
    dit  ROLE_ADMIN 
    dit  ROLE_USER 

вот мои таблицы:

пользователей:

id username password 
--------------------------------- 
    1  admin  ***** 
    2  dit  ***** 

USER_ROLE:

userid roleid 
--------------------- 
    1  1 
    2  2 

роли:

id  authrole 
--------------------- 
    1  ROLE_ADMIN 
    2  ROLE_USER 

UPDATE: я взял этот плохой запрос от этого example on github

+0

Is «Result» Ваш ожидаемый результат? –

+1

'FROM users u JOIN user_role ur ON u.id = ur.userid роли JOIN r ON r.id = ur.roleid WHERE u.username = 'dit'' - использовать реальные объединения вместо подразумеваемых кросс-соединений, это особенно важно если вы не знаете, как проверить, что вы правильно делаете свои соединения. – scragar

ответ

3

Используйте эту (Примечание: ВНУТРЕННИЙ ключевое слово является необязательным):

SELECT u.username 
     ,r.authrole 
    FROM users u 
    INNER JOIN user_role ur 
    ON u.id = ur.userid 
    INNER JOIN roles r 
    ON r.id = ur.roleid 
    WHERE u.username = 'dit' 

Проблема заключалось в том, что вы входите в таблицу ролей, не давая никаких условий для того, как подключиться к таблице. Результатом будет декартово произведение, в котором отображаются все возможные комбинации между соединяемыми таблицами.

Вместо того, чтобы присоединиться к предложению WHERE, лучше (более ясно) использовать синтаксис JOIN. Кроме того, и что более важно, использование синтаксиса JOIN создает разделение проблем. Помещение полей, которые вы используете для объединения таблиц в предложение where, может привести к трудностям в понимании запросов.

Есть по существу четыре различных вида объединений:

  • INNER JOIN: Возвращает все строки, когда есть хотя бы один матч в обеих таблицах

  • LEFT JOIN: Возвращает все строки слева таблицы и совпавшие строки из таблицы справа

  • RIGHT JOIN: Возвращает все строки из таблицы справа и совпавшие строки из левой таблицы

  • ПОЛНЫЙ JOIN: Возвращает все строки, когда есть совпадение в одной из таблиц

+0

Ваша информация о присоединениях верна, но пожалуйста, правильно разберите их.У вас есть три основных типа внешнего соединения: слева, справа и полно, они возвращают null для записей, которые не существуют на соответствующей стороне соединения, и три типа внутреннего соединения, естественные (совпадения на основе столбцов с одинаковым именем , не доверяйте ему), внутренний (имеет предложение on) и крест (не имеет предложения on, вызывает декартово произведение). – scragar

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