仅为sql中的条件选择唯一记录

仅为sql中的条件选择唯一记录,sql,sql-server,distinct,Sql,Sql Server,Distinct,如何仅选择具有访问权的不同用户id的唯一列id值1,即使它们也可能具有访问权列id值2 这是我的查询,返回1和2: SELECT DISTINCT(USER_ID) FROM USER_ACCESS WHERE ACCESS_COLUMN_ID = 1 返回的结果包含具有访问权的userid\u COLUMN\u ID=2 这是我的表格数据 用户ID访问\u列\u ID 1 1 1 2 2.1你可以使用: 由于group by子句,此查询将获取所有用户id

如何仅选择具有访问权的不同用户id的唯一列id值1,即使它们也可能具有访问权列id值2

这是我的查询,返回1和2:

SELECT DISTINCT(USER_ID) FROM USER_ACCESS WHERE ACCESS_COLUMN_ID = 1
返回的结果包含具有访问权的userid\u COLUMN\u ID=2

这是我的表格数据 用户ID访问\u列\u ID 1 1 1 2 2.1你可以使用:

由于group by子句,此查询将获取所有用户id,但仅获取唯一的用户id。然后它将获取它为每个列找到的最小和最大访问列id,如果这两个值都是1,那么用户id将保留在最终结果集中

以上内容将具有良好的性能,因为它只引用表一次

出于您的兴趣,还有其他几种方法可以获得相同的结果。但是,它们都需要表被引用两次。您可能希望自己比较它们的可读性和性能:

不存在

关于独特性的评论

DISTINCT关键字很容易理解,但是使用GROUPBY子句通常可以获得更好的性能。这适用于上述所有解决方案

如果确定用户ID和访问列ID不可能有两个值相同的记录,则可以在上述查询中省略DISTINCT关键字。

您可以使用:

由于group by子句,此查询将获取所有用户id,但仅获取唯一的用户id。然后它将获取它为每个列找到的最小和最大访问列id,如果这两个值都是1,那么用户id将保留在最终结果集中

以上内容将具有良好的性能,因为它只引用表一次

出于您的兴趣,还有其他几种方法可以获得相同的结果。但是,它们都需要表被引用两次。您可能希望自己比较它们的可读性和性能:

不存在

关于独特性的评论

DISTINCT关键字很容易理解,但是使用GROUPBY子句通常可以获得更好的性能。这适用于上述所有解决方案

如果确定用户ID和访问列ID不能有两个值相同的记录,则可以在上述查询中省略DISTINCT关键字。

您可以使用NOT in筛选出访问列ID=2的记录

您可以使用NOT IN筛选出ACCESS\u COLUMN\u ID=2的项目


有很多方法可以完成这项任务。这可能是最灵活的

获取具有所需访问ID的所有用户的列表,并将其与具有不需要的访问ID的用户列表进行对比。这具有可扩展性的优点

SELECT * FROM USER_ACCESS u1
LEFT OUTER JOIN 
    (SELECT USER_ID FROM USER_ACCESS 
     WHERE ACCESS_COLUMN_ID NOT IN ($IDsGoHere$)) u2
ON u1.USER_ID = u2.USER_ID
WHERE u1.ACCESS_COLUMN_ID IN ($IDsGoHere$) AND
u2.USER_ID IS NULL;
几个关键点:

查询可能受益于子选择表u2可能是不同的。这取决于返回的结果数量。 如果您想查看所有具有A访问权限但没有B访问权限的用户,可以相应地替换子选择的WHERE NOT IN子句。 我不知道SQLServer是如何处理优化的,但我见过一些系统,在这些系统中,性能提升被发现用=X和!=X取代了IN X而不是IN X分别为X

编辑1-关于WHERE子句的一般思考

作为一般的经验法则,在计算响应时,考虑是否需要在生成的行的范围内查阅其他行总是很好的。如果您在这种情况下这样做,行必须存在,而同一用户ID的其他行不存在,这通常意味着您需要引入某种类型的联接以消除您不想要的结果。

有许多方法可以完成此任务。这可能是最灵活的

获取具有所需访问ID的所有用户的列表,并将其与具有不需要的访问ID的用户列表进行对比。这具有可扩展性的优点

SELECT * FROM USER_ACCESS u1
LEFT OUTER JOIN 
    (SELECT USER_ID FROM USER_ACCESS 
     WHERE ACCESS_COLUMN_ID NOT IN ($IDsGoHere$)) u2
ON u1.USER_ID = u2.USER_ID
WHERE u1.ACCESS_COLUMN_ID IN ($IDsGoHere$) AND
u2.USER_ID IS NULL;
几个关键点:

查询可能受益于子选择表u2可能是不同的。这取决于返回的结果数量。 如果您想查看所有具有A访问权限但没有B访问权限的用户,可以相应地替换子选择的WHERE NOT IN子句。 我不知道SQLServer是如何处理优化的,但我见过一些系统,在这些系统中,性能提升被发现用=X和!=X取代了IN X而不是IN X分别为X

编辑1-关于WHERE子句的一般思考

作为一般的经验法则,在计算响应时,考虑是否需要在生成的行的范围内查阅其他行总是很好的。如果您在这种情况下这样做,行必须存在,而同一用户ID的其他行不存在,这通常意味着您需要引入某种类型的联接以消除您不想要的结果。

SQL Server会缓存子选择的结果吗?如果是这样的话,在某些情况下可能会出现性能问题
缩放点。SQL Server会缓存子选择的结果吗?如果是这样的话,在某种程度上这可能是一个性能问题。
SELECT    DISTINCT USER_ID
FROM      USER_ACCESS
WHERE     ACCESS_COLUMN_ID = 1
AND       USER_ID NOT IN (
              SELECT USER_ID
              FROM   USER_ACCESS
              WHERE  ACCESS_COLUMN_ID <> 1)
SELECT    DISTINCT USER_ID
FROM      USER_ACCESS UA1
LEFT JOIN USER_ACCESS UA2
       ON UA1.USER_ID = UA2.USER_ID
      AND UA2.ACCESS_COLUMN_ID <> 1
WHERE     UA1.ACCESS_COLUMN_ID = 1
AND       UA2.USER_ID IS NULL
SELECT    DISTINCT USER_ID
FROM      USER_ACCESS
WHERE     ACCESS_COLUMN_ID = 1
EXCEPT
SELECT    USER_ID
FROM      USER_ACCESS
WHERE     ACCESS_COLUMN_ID <> 1
SELECT DISTINCT(USER_ID) FROM USER_ACCESS WHERE ACCESS_COLUMN_ID = 1 and 
USER_ID NOT IN (
  SELECT DISCTINCT (USER_ID) FROM USER_ACCESS WHERE ACCESS_COLUMN_ID = 2
)
SELECT * FROM USER_ACCESS u1
LEFT OUTER JOIN 
    (SELECT USER_ID FROM USER_ACCESS 
     WHERE ACCESS_COLUMN_ID NOT IN ($IDsGoHere$)) u2
ON u1.USER_ID = u2.USER_ID
WHERE u1.ACCESS_COLUMN_ID IN ($IDsGoHere$) AND
u2.USER_ID IS NULL;