SQL 查询以根据另一列的值查找唯一列值
SQL Query to find unique column value based on values from another column
我有一个 SQL 服务器 table 像这样
此 table 的架构和示例插入查询以构建此 table:
CREATE TABLE demotable (
Id int,
PrivilageId int,
RoleId int
);
insert into demotable values (1 ,40, 101)
insert into demotable values (2 ,12, 101)
insert into demotable values (3 ,40, 102)
insert into demotable values (4 ,40, 104)
insert into demotable values (5 ,12, 128)
insert into demotable values (6 ,40, 107)
insert into demotable values (7 ,17, 103)
insert into demotable values (8 ,17, 107)
insert into demotable values (9 ,15, 138)
insert into demotable values (10 ,15, 102)
insert into demotable values (11 ,17, 104)
insert into demotable values (12 ,12, 101)
如您所见,如果我想查看特权 ID 40 的所有 RoleID,我可以通过此查询轻松获得。
select * from DemoTable where PrivilageID = 40
这给了我 101, 102, 104, 107
的结果
但是我的要求正好相反。我知道这个特定组合 101, 102, 104, 107
只有一个 PrivilageID
。我需要一个可以传递 101, 102, 104, 107
的查询,我将得到 40
的输出
我尝试的是:我创建了这样的交叉查询:
select PrivilageId from DemoTable where RoleID = 101
intersect
select PrivilageId from DemoTable where RoleID = 102
intersect
select PrivilageId from DemoTable where RoleID = 104
intersect
select PrivilageId from DemoTable where RoleID = 107
这个可行,但还有更好的方法吗?
如果我理解正确,您可以尝试 HAVING
条件聚合函数 COUNT
和 DISTINCT
条件。
我们只需要在 CASE WHEN
表达式中添加过滤器 RoleId
,计数可能等于您的 RoleId
数字。
SELECT PrivilageId
FROM DemoTable
GROUP BY PrivilageId
HAVING COUNT(DISTINCT CASE WHEN RoleId IN (101, 102, 104, 107) THEN RoleId END) = 4
有很多方法可以做到这一点。例如,您可以使用已经提到的 HAVING
。另一种选择是使用 EXISTS
.
SELECT DISTINCT d.privilageid FROM demotable d WHERE
EXISTS(SELECT 1 FROM demotable WHERE roleid = 101 AND d.privilageid = privilageid) AND
EXISTS(SELECT 1 FROM demotable WHERE roleid = 102 AND d.privilageid = privilageid) AND
EXISTS(SELECT 1 FROM demotable WHERE roleid = 104 AND d.privilageid = privilageid) AND
EXISTS(SELECT 1 FROM demotable WHERE roleid = 107 AND d.privilageid = privilageid)
我有一个 SQL 服务器 table 像这样
此 table 的架构和示例插入查询以构建此 table:
CREATE TABLE demotable (
Id int,
PrivilageId int,
RoleId int
);
insert into demotable values (1 ,40, 101)
insert into demotable values (2 ,12, 101)
insert into demotable values (3 ,40, 102)
insert into demotable values (4 ,40, 104)
insert into demotable values (5 ,12, 128)
insert into demotable values (6 ,40, 107)
insert into demotable values (7 ,17, 103)
insert into demotable values (8 ,17, 107)
insert into demotable values (9 ,15, 138)
insert into demotable values (10 ,15, 102)
insert into demotable values (11 ,17, 104)
insert into demotable values (12 ,12, 101)
如您所见,如果我想查看特权 ID 40 的所有 RoleID,我可以通过此查询轻松获得。
select * from DemoTable where PrivilageID = 40
这给了我 101, 102, 104, 107
但是我的要求正好相反。我知道这个特定组合 101, 102, 104, 107
只有一个 PrivilageID
。我需要一个可以传递 101, 102, 104, 107
的查询,我将得到 40
我尝试的是:我创建了这样的交叉查询:
select PrivilageId from DemoTable where RoleID = 101
intersect
select PrivilageId from DemoTable where RoleID = 102
intersect
select PrivilageId from DemoTable where RoleID = 104
intersect
select PrivilageId from DemoTable where RoleID = 107
这个可行,但还有更好的方法吗?
如果我理解正确,您可以尝试 HAVING
条件聚合函数 COUNT
和 DISTINCT
条件。
我们只需要在 CASE WHEN
表达式中添加过滤器 RoleId
,计数可能等于您的 RoleId
数字。
SELECT PrivilageId
FROM DemoTable
GROUP BY PrivilageId
HAVING COUNT(DISTINCT CASE WHEN RoleId IN (101, 102, 104, 107) THEN RoleId END) = 4
有很多方法可以做到这一点。例如,您可以使用已经提到的 HAVING
。另一种选择是使用 EXISTS
.
SELECT DISTINCT d.privilageid FROM demotable d WHERE
EXISTS(SELECT 1 FROM demotable WHERE roleid = 101 AND d.privilageid = privilageid) AND
EXISTS(SELECT 1 FROM demotable WHERE roleid = 102 AND d.privilageid = privilageid) AND
EXISTS(SELECT 1 FROM demotable WHERE roleid = 104 AND d.privilageid = privilageid) AND
EXISTS(SELECT 1 FROM demotable WHERE roleid = 107 AND d.privilageid = privilageid)