如何根据值检查和排除 SQL 中的项目

How to check and exclude items in SQL based on values

提问人:B2CAccount123 提问时间:11/17/2023 更新时间:11/17/2023 访问量:68

问:

我有一个数据库,我需要在其中获取无法登录我们服务的用户列表。我们有包含 ID (uID) 和 auth_field 的行,这些 ID 和 根据用户是否能够登录而为我们提供“true”或“false”。

uID auth_field
1234 “假”
8788 “假”
1234 “真”
8788 “假”
1234 “真”
8788 “假”
6666 “假”

根据上面的输出,1234 能够登录,因此我想从我的查询中排除包含该 uID 的所有结果,包括“false”字段。

SELECT uID, COUNT(uID)
FROM database
GROUP BY uID
HAVING (auth_field) ='false'

这为我提供了身份验证失败的用户列表,但我需要排除具有 auth_field = 'true' 的重复项

如果有一个“真实”auth_field,我有点不知所措,不知道如何返回排除每个 uID 的回报。

我的想法是在这里的某个地方有以下内容,但无法使其工作 'WHERE NOT auth_field = 'true'

sql snowflake-cloud-data-platform

评论

0赞 jarlh 11/17/2023
要做什么?我希望在 HAVING 子句中有一个聚合函数。HAVING (auth_field) ='false'
0赞 Isolated 11/17/2023
有几种方法可以做到这一点。一种是使用 ,例如 。except 子句也会自动对用户进行重复数据删除。exceptselect uid from table where auth_field = 'false' except select uid from table where auth_field = 'true'
0赞 jarlh 11/17/2023
您能否指定预期的结果。(即提供一个完整的最小可重复示例
0赞 Thorsten Kettner 11/17/2023
“这给了我一个身份验证失败的用户列表” - 它不应该。您的查询无效。您按用户 ID 分组,但在子句中选中 .哪一个?每个用户 ID 有几行,因此没有可以检查的行。查询必须导致错误,但你说它不会?我知道MySQL的这种行为在作弊模式下运行,允许这种无效的查询,并且只返回任意结果。其他 DBMDS 应引发错误。HAVINGauth_fieldauth_field
0赞 Thorsten Kettner 11/17/2023
您可以更改为 .这是因为似乎是一个字符串,而字母表中的“true”位于“false”之后。因此,如果用户 ID 的最大auth_field为“false”,则其所有auth_fields均为“false”。HAVING (auth_field) ='false'HAVING MAX(auth_field) ='false'auth_field

答:

0赞 Hamid Molareza 11/17/2023 #1

请试试这个:

SELECT uId
FROM database
GROUP BY uId
HAVING COUNT(*) = SUM(CASE WHEN auth_field = 'false' THEN 1 ELSE 0 END)

或者以更简单的形式:

SELECT uId
FROM database
GROUP BY uId
HAVING COUNT(*) = SUM(IF(auth_field = 'false', 1, 0));

此外,这也有效:

SELECT uId
FROM database
GROUP BY uId
HAVING SUM(auth_field = 'true') = 0;

例如,数据的输出如下所示:

8788
6666

注意:如果数据类型为布尔值,请使用 ,否则false'false'

0赞 Teja Goud Kandula 11/17/2023 #2
with cte as (
SELECT 
    uID, listagg(distinct auth_field) within group (order by auth_field) as auth
FROM database
GROUP BY 1
)
select 
   uId
from cte 
   where auth = 'false'
0赞 Kathmandude 11/17/2023 #3

如果每次登录尝试都失败,则每个 uIdauth_field 个登录尝试都为“false”。因此,您可以将代码修改为..minmax

select uID, count(uID)
from  database
group by uID
having min(auth_field) = 'false' and max(auth_field) = 'false'

或者,如果 auth_field 还不是 ,则可以转换为 ,则 ,则需要booleanbooleanintsum = 0

select uID, count(uID)
from  database
group by uID
having sum(auth_field::boolean::int) = 0

评论

0赞 Thorsten Kettner 11/17/2023
您可以删除 .最大auth_field为“false”就足够了,因为这样用户 ID 就不能有“true”。min(auth_field) = 'false' and
1赞 Kathmandude 11/17/2023
正确,但同时包含最小值和最大值使其更不言自明,而不是依赖于 f<t 的字母顺序