分组,使用SQL Server中的条件

时间:2018-06-17 03:25:00

标签: sql-server group-by having where-in exact-match

SeqNo   ProfileId   MenuId
--------------------------
 1      P1001        1001
 2      P1001        1002
 3      P1001        1004
 4      P1001        1005
 5      P1001        1006
 6      P1001        1007
 7      P1001        1008
 8      P1001        1009
 9      P1001        1010
10      P1002        1001
11      P1002        1002
12      P1002        1003
13      P1002        1004
14      P1002        1005

该方案是检查给定的ProfileId是否存在特定的MenuId

假设我的输入MenuId设置为(1001, 1002, 1003, 1004, 1005),那么它必须返回精确匹配条件P1002

如果MenuId设置为(1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010),则必须返回P1001

但如果我使用group bywhere in条件,则会同时返回P1001, P1002

如何获得上述情况的完全匹配条件?

2 个答案:

答案 0 :(得分:0)

如果您想匹配完全匹配的配置文件,那么一个选项是聚合并断言不同的和总计数:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>

<ul class="nav nav-pills">
  <li class="nav-item">
    <a class="nav-link active" href="#">Active Active Active Active Active Active Active Active Active</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link Link Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled" href="#">Disabled Disabled</a>
  </li>
</ul>

Demo

SELECT ProfileId FROM yourTable GROUP BY ProfileId HAVING SUM(CASE WHEN MenuId NOT IN (1001, 1002, 1003, 1004, 1005) THEN 1 ELSE 0 END) = 0 AND COUNT(DISTINCT MenuId) = 5 AND COUNT(*) = 5; 子句中的三个条件断言:

  • 该个人资料
  • 没有显示超出1001到1005的菜单项其他
  • 该个人资料有5个不同的菜单项
  • 该个人资料只有5个总菜单项

答案 1 :(得分:0)

我非常喜欢该集合的字符串比较方法。如果你有string_agg那么你可以使用它,否则stuff / xml路径方法也很好

例如

drop table t
go
create table t(
SeqNo  int ,ProfileId  varchar(5),  MenuId varchar(4));
go
insert into t values
( 1  ,    'P1001'     ,   1001),
( 2  ,    'P1001'     ,   1002),
( 3  ,    'P1001'     ,   1004),
( 4  ,    'P1001'     ,   1005),
( 5  ,    'P1001'     ,   1006),
( 6  ,    'P1001'     ,   1007),
( 7  ,    'P1001'     ,   1008),
( 8  ,    'P1001'     ,   1009),
( 9  ,    'P1001'     ,   1010),
(10  ,    'P1002'     ,   1001),
(11  ,    'P1002'     ,   1002),
(12  ,    'P1002'     ,   1003),
(13  ,    'P1002'     ,   1004),
(14  ,    'P1002'     ,   1005);

select s.profileid
from
(
select  distinct t.profileid,
        maskdetail = STUFF((
          SELECT ',' + t1.menuid
          FROM t t1
          WHERE t1.profileid = t.profileid
          FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
from t

) s 
where s.maskdetail = concat('1001',',',1002,',',1003,',',1004,',','1005')

profileid
---------
P1002

(1 row(s) affected)

您必须确保您的设置和数据都有序。