2017-09-11 2 views
1

주요 아이디어를 기반으로 가입

  • 사용자 hasMany 역할 (데이터가 테이블에 저장됩니다 users, roles, user_role을) 내가 알고 싶어
  • 사용자는이 데이터는이어서 다른 결과
,691,363에 join ED 것이다
  • 관리자 또는 클라이언트 인 내가 일하고 있어요 어떻게이

    잘못 왜이 결과이기 때문에 내가 외국 상태

    SELECT 
        `users`.`id`, 
        `users`.`name`, 
        `roles`.`display_name` 
    FROM `users` 
        JOIN role_user ON users.id = role_user.user_id 
        JOIN roles ON role_user.role_id = roles.id 
    

    을 뭘하는지 (210)

    은 내가

    id  Name Display name 
    
    1  admin Admin 
    2  admin2 Admin 
    3  client Client 
    7  test Admin 
    

    를 원하는 것은
    id  Name Display name 
    
    1  admin Admin 
    1  admin Client 
    2  admin2 Admin 
    2  admin2 Client 
    3  client Client 
    7  test  Admin 
    7  test  Client 
    

    를 얻을 수 이 작품을 만들려면

    • 사용 집계는 어떻게 든
    • 사용하는 경우는 어떻게 든

  • 은 당신의 아이디어에 감사드립니다 어떻게 든 데이터의 하위 집합에 가입!

    [업데이트] 다음은 문제를 설명하는 sqlFiddle입니다.

    +0

    는 SQL 바이올린을 확인하시기 바랍니다에게 있습니다. 우리는 귀하의 데이터와 테이블 구조를 이해해야합니다. – droidnation

    +0

    role_user 테이블에 문제가 있습니다. 동일한 user_id에 2 행을 삽입하는 이유는 무엇입니까? 1은 관리자 용이고 1은 클라이언트 용입니다. 둘 중 하나를 제거하면 결과를 얻을 수 있습니다. –

    답변

    0

    이 쿼리를보십시오 : 귀하의 요청에

    SELECT users.`id`, users.`name`, MIN(roles.`display_name`) 
    FROM `users` users, `role_user` role_user, `roles` roles 
    WHERE users.id = role_user.user_id AND role_user.role_id = roles.id 
    GROUP BY users.`id` 
    

    당신이 당신에게 결과의 모든 가능한 조합을주고 테이블을 조인. 이 쿼리는 발견 된 각 userId에 대해 role_user/roles 만 선택합니다.

    편집 :

    +0

    결과에 데이터가 여전히 중복되어 있기 때문에 문제가 해결되지 않습니다. 다음과 같은 방식으로 사용자 역할에 대해 하나의 결과 만 가져와야합니다. 사용자가 admin이고 클라이언트가 admin 인 경우. 사용자가 admin이면 admin을 원합니다. 사용자가 클라이언트 인 경우 클라이언트를 원합니다. –

    +0

    몇 가지 변경 사항 : 영문자 순으로 가장 낮은 값을 선택하려면 MIN()을 추가 했으므로 둘 다 존재하면 CLIENT 앞에 ADMIN을 선택합니다. 또한 각 사용자를 한 번만 표시하기를 원하기 때문에 "GROUP BY"를 추가했습니다. – Franky

    0
    SELECT 
         `users`.`id`, 
         `users`.`name`, 
         `roles`.`display_name` 
    FROM `users` 
    LEFT JOIN role_user ON users.id = role_user.user_id 
    left JOIN roles ON role_user.role_id = roles.id 
    
    +0

    문제가 발생하기 전에 ID를 확인하십시오. –

    0

    이 솔루션은 잘 작동합니다 (그래서 "관리자" "클라이언트"전에 선택된다)에만 고유 한 사용자와 "분"의 순으로 가장 낮은 역할을 선택하는 선택하는 "으로 그룹을"추가 당신을 위해 여기

    select * from users 
    where users.id in (
    select users.id FROM users 
        JOIN role_user ON (users.id = role_user.user_id) 
        JOIN roles ON (role_user.role_id = roles.id) 
        where roles.display_name like 'admin' 
    ) 
    Union 
    select * from users 
    where users.id not in (
    select users.id FROM users 
        JOIN role_user ON (users.id = role_user.user_id) 
        JOIN roles ON (role_user.role_id = roles.id) 
        where roles.display_name like 'admin' 
    ); 
    

    바이올린 : http://sqlfiddle.com/#!9/0fabba/42

    나는 하위 쿼리에 대한 뷰를 작성하는 것이 좋습니다,하지만 난 인터넷에 그것을 할 수

    ddle.

    Create or replace view admin_list as 
        select users.id FROM users 
        JOIN role_user ON (users.id = role_user.user_id) 
        JOIN roles ON (role_user.role_id = roles.id) 
        where roles.display_name like 'admin'; 
    

    그런 다음 쿼리가 훨씬 컴팩트 될 것입니다 :

    예 뷰를 사용하여

    select * from users 
    where users.id in (
        select users.id FROM admin_list 
    ) 
    Union 
    select * from users 
    where users.id not in (
        select users.id FROM admin_list 
    ); 
    
    0

    내 자신의 솔루션은 사용자의를 얻을 수있는 뷰를 만들려면 다음

    • 했다 역할 ID (관리자 또는 클라이언트)
    • 보기와 결합

    은 특히 여기에보기

    CREATE VIEW vw_users_role_by_priority AS (
        SELECT 
        role_user.user_id, 
        min(role_user.role_id) AS 'role_id' 
        FROM role_user 
        JOIN roles ON role_user.role_id = roles.id 
        GROUP BY role_user.user_id 
    ); 
    

    입니다 그리고 여기에 최종 쿼리

    SELECT 
        `users`.`id`, 
        `roles`.display_name 
    FROM `users` 
        JOIN vw_users_role_by_priority ON vw_users_role_by_priority.user_id = users.id 
        JOIN roles ON roles.id = vw_users_role_by_priority.role_id 
    ORDER BY `users`.`name` ASC;