陷入PostgreSQL搜索查询
这是我尝试过的问题陷入PostgreSQL搜索查询,sql,postgresql,Sql,Postgresql,这是我尝试过的问题 I have 3 tables: 1. users -- _id -- firstname 3. roles -- _id -- user_id -- alias // admin, hr etc.. 2. userroles -- user_id -- role_id 我想查询在给定角色中具有多个角色的用户。例如,仅限管理员或hr用户。当前查询只匹配确切的角色,而不匹配多个角色。你能给我一些建议吗?你说得对。但是,正确的逻辑应该是按用户聚合,然后断言不同数量的角色与
I have 3 tables:
1. users
-- _id
-- firstname
3. roles
-- _id
-- user_id
-- alias // admin, hr etc..
2. userroles
-- user_id
-- role_id
我想查询在给定角色中具有多个角色的用户。例如,仅限管理员或hr用户。当前查询只匹配确切的角色,而不匹配多个角色。你能给我一些建议吗?你说得对。但是,正确的逻辑应该是按用户聚合,然后断言不同数量的角色与您在本例2中预期的不同角色数量(ad和gm)相匹配 首先,您不希望左连接,因为根据您想要的定义,将有匹配项 其次,您可以通过调整WHERE和GROUP by子句来处理此问题: 2是给定数组的数组长度,因此也可以将其参数化 对firstname的筛选应该在聚合之前进行,而不是之后 假设用户多次不具有相同的角色,则使用COUNT*。如果可能,请改用COUNTDISTINCT r.alias 例如,仅限管理员或hr用户 我想“ad”是admin的缩写。如果您想查询“hr”,为什么您的查询不包含“hr” 数组_aggr.alias@>“{ad,gm}”
这需要“ad”和“gm”。如果您只需要其中一个,请使用&&,而不是@>我不知道PostgreSQL支持的ANSI/ISO SQL 2003可选函数依赖项功能?你能发布创建表结构吗?@RaymondNijland确实如此,因为Postgres最接近ANSI标准。但是,它仅在合法(即仅断开MySQL查询的完整组)无法运行时才支持它。@RaymondNijland SQL Server不支持它,Oracle AFAIK也不支持它。不过,拥有它很好。@TimBiegeleisen是的,我希望有一些关于该功能的文档。。我从来没有读过这是可能的。由于T301功能依赖项位于PostgreSQL 11文档中的。。。这就是为什么我对PostgreSQL支持它感到惊讶。。SQL Server不支持它,Oracle AFAIK也不支持它。不过,拥有它很好。事实上,当RDMS在分组时可以使用函数依赖关系时,RDMS需要做的工作就更少了。但是使用MINr.alias MAXr.alias这不会给出名为Admin的用户的列表,并且在ad或gm角色中使用以太网。这对我有用,谢谢。但我唯一不明白的是,为什么需要使用MINr.alias MAXr.alias,而不使用它HAVING@Kapil如果所有具有别名广告的匹配用户也始终具有别名gm,那么在没有HAVING子句的情况下,它将巧合地起作用。如果没有,那么您肯定需要HAVING子句来获得正确的行为。hi@gordonLinoff sitll HAVING error:8行或附近的语法错误:r.alias@>{ad,gm}^删除括号时出错:运算符不存在:字符变化@>未知行8:r.alias@>{ad,gm}@Kapil。我以更典型的方式重写了数组比较,无论是好是坏。我要找的正是:-选择u.\u id、u.firstname、u.lastname、u.email、,array_aggr.alias as roles FROM users u JOIN userroles ur ON u._id=ur.user_id JOIN roles r ON ur.role_id=r._id其中u.firstname='Admin'和r.alias IN'ad'、'tc'、'gm'、'hr'组中的r.alias由u添加到u。如果我得到多个r.alias,其中我想比较数组的任意一侧,然后返回用法,例如,在r.alias中我得到了ad、hr,gm与给定数组gm进行比较,如将左侧比较到右侧,并返回用户列表,其中任何一个在任何一侧匹配。
SELECT u._id, u.firstname, u.lastname, array_agg(r.alias) as roles
FROM users u
LEFT OUTER JOIN userroles ur ON (u._id = ur.user_id)
LEFT OUTER JOIN roles r ON (ur.role_id = r._id)
GROUP BY u._id
HAVING u.firstname='Admin' AND array_agg(r.alias) @> '{"ad", "gm"}'
SELECT
u._id, u.firstname, u.lastname, array_agg(r.alias) as roles
FROM users u
LEFT OUTER JOIN userroles ur ON
u._id = ur.user_id
LEFT OUTER JOIN roles r
ON ur.role_id = r._id
WHERE
u.firstname = 'Admin' AND
r.alias IN ('ad', 'gm')
GROUP BY
u._id
HAVING
MIN(r.alias) <> MAX(r.alias);
SELECT u._id, u.firstname, u.lastname, array_agg(r.alias) as roles
FROM users u JOIN
userroles ur
ON u._id = ur.user_id JOIN
roles r
ON ur.role_id = r._id
WHERE u.firstname = 'Admin' AND
array['ad', 'gm'] @> array[r.alias]
GROUP BY u._id -- this is fine assuming `_id` is unique
HAVING COUNT(*) = 2;