用于检查SQL Server中的组中是否存在确切ID(3+条记录)的逻辑
我有一些样本数据,如:用于检查SQL Server中的组中是否存在确切ID(3+条记录)的逻辑,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我有一些样本数据,如: INSERT INTO mytable ([FK_ID], [TYPE_ID]) VALUES (10, 1), (11, 1), (11, 2), (12, 1), (12, 2), (12, 3), (14, 1), (14, 2), (14, 3), (14, 4), (15, 1), (15, 2), (15, 4) 现在,我试图通过FK_ID检查每个组中1、2和3的TYPE_ID值是否完全匹配 因此,预期
INSERT INTO mytable
([FK_ID], [TYPE_ID])
VALUES
(10, 1),
(11, 1), (11, 2),
(12, 1), (12, 2), (12, 3),
(14, 1), (14, 2), (14, 3), (14, 4),
(15, 1), (15, 2), (15, 4)
现在,我试图通过FK_ID检查每个组中1、2和3的TYPE_ID值是否完全匹配
因此,预期输出如下所示:
10,1这应该失败
在FK_ID=10组中,我们只有一条记录
11,1,11,2这也应该失败
在FK_ID=11组中,我们有两条记录。
12,1,12,2,12,3这应该通过
在FK_ID=12组中,我们有两条记录。
所有类型的ID都与1、2和3的值完全匹配。
14,1,14,2,14,3,14,4这也应该失败
因为我们这里有4张唱片。
15,1,15,2,15,4这也应该失败
即使我们有三条记录,它也应该失败,因为这里的类型_ID 1、2、4与所需的匹配项1、2、3不匹配。
以下是我的尝试:
select * from mytable t1
where exists (select COUNT(t2.TYPE_ID)
from mytable t2 where t2.FK_ID = t1.FK_ID
and t2.TYPE_ID IN (1, 2, 3)
group by t2.FK_ID having COUNT(t2.TYPE_ID) = 3);
这并没有像预期的那样工作,因为它也传递给FK_ID=14,它有四条记录
演示:
此外,我们如何使其通用,以便如果我们需要检查4个或更多类型ID值,如1,2,3,4或1,2,3,4,5,我们可以通过更新几个值轻松完成这项工作。以下查询将满足您的要求:
select fk_id
from t
group by fk_id
having sum(case when type_id in (1, 2, 3) then 1 else 0 end) = 3 and
sum(case when type_id not in (1, 2, 3) then 1 else 0 end) = 0;
这假设您没有重复对,尽管这取决于您想要如何处理重复项,它可能与使用一样简单,从selectdistinct*fromt
至于一般性,您需要更新in列表和3
如果您想要更通用的东西:
with vals as (
select id
from (values (1), (2), (3)) v(id)
)
select fk_id
from t
group by fk_id
having sum(case when type_id in (select id from vals) then 1 else 0 end) = (select count(*) from vals) and
sum(case when type_id not in (select id from vals) then 1 else 0 end) = 0;
您可以使用以下代码:
SELECT y.fk_id FROM
(SELECT x.fk_id, COUNT(x.type_id) AS count, SUM(x.type_id) AS sum
FROM mytable x GROUP BY (x.fk_id)) AS y
WHERE y.count = 3 AND y.sum = 6
为了使其通用,您可以将y.count与N相等,y.sum与N*N-1/2相等,其中N是您要查找的数字1,2,…,N.您可以尝试此查询。计数和区分用于消除重复记录
SELECT
[FK_ID]
FROM
@mytable T
GROUP BY
[FK_ID]
HAVING
COUNT(DISTINCT CASE WHEN [TYPE_ID] IN (1,2,3) THEN [TYPE_ID] END) = 3
AND COUNT(CASE WHEN [TYPE_ID] NOT IN (1,2,3) THEN [TYPE_ID] END) = 0
试试这个:
select FK_ID,count(distinct TYPE_ID) from mytable
where TYPE_ID<=3
group by FK_ID
having count(distinct TYPE_ID)=3
您应该将CTE与您在Q中提到的动态传递值一起使用
WITH CTE
AS (
SELECT FK_ID,
COUNT(*) CNT
FROM #mytable
GROUP BY FK_ID
HAVING COUNT(*) = 3) <----- Pass Value here What you want to Display Result,
CTE1
AS (
SELECT T.[ID],
T.[FK_ID],
T.[TYPE_ID],
ROW_NUMBER() OVER(PARTITION BY T.[FK_ID] ORDER BY
(
SELECT NULL
)) RN
FROM #mytable T
INNER JOIN CTE C ON C.FK_ID = T.FK_ID),
CTE2
AS (
SELECT C1.FK_ID
FROM CTE1 C1
GROUP BY C1.FK_ID
HAVING SUM(C1.TYPE_ID) = SUM(C1.RN))
SELECT TT1.*
FROM CTE2 C2
INNER JOIN #mytable TT1 ON TT1.FK_ID = C2.FK_ID;
请描述您想要的输出。我只需要FK_ID=12的记录,因为这些记录只符合3中提到的要求。这在:10,1,10,2,10,1?@P.Kouvarakis上不会成功吗。我最初是说没有重复的。我对答案进行了编辑,以解释如果存在重复项,该怎么办。如果使用from select distinct*from t,它还将匹配10,1,10,2,10,3,10,1您是否可以将和countdistinct type_id=3添加到having子句中?
ID FK_ID TYPE_ID
4 12 1
5 12 2
6 12 3