我怎样才能选择仅具有ACCESS_COLUMN_ID值1的不同用户ID,即使它们也可能具有ACCESS_COLUMN_ID值2。
这是我的查询返回1和2:
SELECT DISTINCT(USER_ID) FROM USER_ACCESS WHERE ACCESS_COLUMN_ID = 1
返回的结果包含同时拥有ACCESS_COLUMN_ID = 2
的用户ID。
Here is my table data
USERID ACCESS_COLUMN_ID
1 1
1 2
2 1
我期待USERID 2仅作为我的查询结果
答案 0 :(得分:5)
您可以使用HAVING
:
SELECT USER_ID
FROM USER_ACCESS
GROUP BY USER_ID
HAVING MIN(ACCESS_COLUMN_ID) = 1
AND MAX(ACCESS_COLUMN_ID) = 1
此查询将获取所有user_id
,但由于group by
子句,只会获得唯一的access_column_id
。然后,它将为每个值找到它找到的最小值和最大值user_id
,如果这两个值都是1,则SELECT DISTINCT USER_ID
FROM USER_ACCESS UA1
WHERE UA1.ACCESS_COLUMN_ID = 1
AND NOT EXISTS (
SELECT 1
FROM USER_ACCESS UA2
WHERE UA1.USER_ID = UA2.USER_ID
AND UA2.ACCESS_COLUMN_ID <> 1)
将保留在最终结果集中。
上面会有很好的表现,因为它只引用一次表。
为了您的兴趣,还有其他几种方法可以获得相同的结果。但是他们都需要将表引用两次。您可能希望自己比较它们的可读性和性能:
NOT EXISTS
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
外部自我加入
这通常比前两个解决方案具有更好的性能:
NULL
最后一个ACCESS_COMUN_ID <> 1
条件检查外部联接是否产生任何匹配(使用MINUS
)。
<强>除非强>
这是SQL Server特有的语法,但很容易理解(Oracle有类似的SELECT DISTINCT USER_ID
FROM USER_ACCESS
WHERE ACCESS_COLUMN_ID = 1
EXCEPT
SELECT USER_ID
FROM USER_ACCESS
WHERE ACCESS_COLUMN_ID <> 1
);
DISTINCT
备注DISTINCT
GROUP BY
关键字很容易理解,但通过使用USER_ID
子句,通常可以获得更好的性能。这可以应用于上述所有解决方案。
如果确定ACCESS_COLUMN_ID
和DISTINCT
的两个记录不能有相同的值,那么function myFunction(array) {
var largest = array.replace(/\D/g, '');
for (var i = 0; i < array.length; i++) {
if (largest < array[i]) {
largest = array[i];
}
}
console.log(largest);
}
myFunction([509 - 111 - 1111, 509 - 222 - 2222, 509 - 333 - 3333]);
关键字可以在上述查询中省略。
答案 1 :(得分:0)
您可以使用NOT IN
过滤掉ACCESS_COLUMN_ID = 2
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
)
答案 2 :(得分:0)
您可以通过多种方式完成此任务。这可能是最灵活的。
获取具有所需访问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
可能DISTINCT
。这取决于返回的结果数量。WHERE NOT IN
子句。我不知道SQLServer如何处理优化,但我看到系统发现性能增益取代了IN (X)
和NOT IN (X)
= X
和!= X
分别
作为一般经验法则,在计算响应时,考虑是否需要查询不在生成行范围内的其他行总是好的。如果你这样做(在这种情况下,行必须存在,并且同一USER_ID
不存在其他行),通常需要引入某种类型的连接以消除结果不想要。