简体   繁体   English

SQL Server 多连接返回重复值

[英]SQL Server Multiple join return duplicated values

I have 4 tables under my database TEST:我的数据库 TEST 下有 4 个表:

  1. USER用户
  2. USER_GROUP_PERMISSION USER_GROUP_PERMISSION
  3. PERMISSION_TYPE PERMISSION_TYPE
  4. GROUPS团体

when I join the above tables using inner join and cross join instead of returning 520 rows it returns 2600 rows, most of the values duplicated当我使用内连接和交叉连接而不是返回 520 行连接上面的表时,它返回 2600 行,大多数值重复

I need a final output without duplicates我需要一个没有重复的最终输出

Query:询问:

select user.*
from TEST.USER user 
    inner join TEST.USER_GROUP_PERMISSION user_grp1
        on user.APPLICATION_ID = user_grp1.APPLICATION_ID 
    inner join TEST.PERMISSION_TYPE permission2_
        on user_grp1.PERMISSION_TYPE_ID = permission2_.PERMISSION_TYPE_ID
    inner join TEST.GROUPS groups
        on user_grp1.GROUP_ID = groups.GROUP_ID
    cross join TEST.PERMISSION_TYPE permission4_ 
where user_grp1.PERMISSION_TYPE_ID = permission4_.PERMISSION_TYPE_ID
    and groups.GROUP_ID in (101)
    and permission4_.PERMISSION_TYPE in (0 , 1 , 2 , 3 , 4 , 5 , 6)
    and user.NAME = 'ROBIN'
    and user.ACTIVE = '1'
order by upper(user.DISPLAY_VERSION) asc

If you want to show users without duplicates, then select from users only.如果要显示没有重复的用户,请仅从用户中选择。 Don't join!不要加入! This is what the query should look like:查询应如下所示:

select * from users where ...

Your query is hard to understand, especially with the permission type joined twice, once even with an inner join disguised as a cross join.您的查询很难理解,尤其是权限类型加入了两次,甚至一次内部联接伪装成交叉联接。 It looks like you want the user ROBIN provided he is active and his application has a group permission for group 101 and type 1 to 6. This would be:看起来您希望用户 ROBIN 前提是他处于活动状态并且他的应用程序具有组 101 的组权限并键入 1 到 6。这将是:

select *
from test.user
where name = 'ROBIN'
and active = '1'
and application_id in
(
  select application_id
  from test.user_group_permission
  where group_id = 101
  and permission_type_id in 
  (
    select permission_type_id
    from test.permission_type
    where permission_type in (0, 1, 2, 3, 4, 5, 6)
  )
)
order by upper(display_version);

(You can also join permission_type to user_group_permission , if you like that better than IN .) (你也可以将permission_type加入user_group_permission ,如果你比IN更喜欢它。)

I would phrase the query using exists :我会使用exists来表达查询:

select user.*
from TEST.USER user 
where user.NAME = 'ROBIN'
      user.ACTIVE = '1' and
      exists (select 1
              from TEST.USER_GROUP_PERMISSION user_grp1 join
                   TEST.PERMISSION_TYPE permission2_
                   on user_grp1.PERMISSION_TYPE_ID = permission2_.PERMISSION_TYPE_ID join
                   TEST.GROUPS groups
                   on user_grp1.GROUP_ID = groups.GROUP_ID join 
                   TEST.PERMISSION_TYPE permission4_ 
                   on user_grp1.PERMISSION_TYPE_ID = permission4_.PERMISSION_TYPE_ID
              where user.APPLICATION_ID = user_grp1.APPLICATION_ID 
                    groups.GROUP_ID in (101) and
                    permission4_.PERMISSION_TYPE in (0 , 1 , 2 , 3 , 4 , 5 , 6)
       )
order by upper(user.DISPLAY_VERSION) asc

Then, the most important index for this is on users(name, active, upper(DISPLAY_VERSION)) .然后,最重要的索引是users(name, active, upper(DISPLAY_VERSION))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM