用于检查SQL Server

时间:2017-10-13 18:40:10

标签: 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值完全匹配。

所以,预期的输出就像:

  1. (10, 1)这应该失败
    • 与小组FK_ID = 10一样,我们只有一条记录
  2. (11, 1), (11, 2)这也应该失败
    • 与小组FK_ID = 11一样,我们有两条记录。
  3. (12, 1), (12, 2), (12, 3)这应该通过
    • 与小组FK_ID = 12一样,我们有两条记录。
    • 所有TYPE_ID都与1, 2 & 3值完全匹配。
  4. (14, 1), (14, 2), (14, 3), (14, 4)这也应该失败
    • 我们这里有4条记录。
  5. (15, 1), (15, 2), (15, 4)这也应该失败
    • 即使我们有三条记录,它也会失败,因为此处TYPE_ID(1,2,4)与所需的匹配(1,2,3)不匹配。
  6. 这是我的尝试:

    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,它有四个记录。

    演示:SQL Fiddle

    此外,我们如何使其成为通用的,以便我们需要检查4个或更多TYPE_ID值,如(1,2,3,4)或(1,2,3,4,5) ,我们可以通过更新几个值轻松地做到这一点。

5 个答案:

答案 0 :(得分:3)

以下查询将执行您想要的操作:

active = true;
while active == true
   active = input('Enter true or false ' );
   disp(rand)
   pause(1)
end

这假设您没有重复对(虽然取决于您希望如何处理重复项,但它可能就像使用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; )一样简单。

对于"通用性",您需要更新from (select distinct * from t) t列表和in

如果你想要更通用的东西:

3

答案 1 :(得分:1)

您可以使用此代码:

N

为了使其成为通用,您可以将y.count与N*(N-1)/2和y.sum与N相等,其中(1, 2, ..., N)是您要查找的数字{{1}}。

答案 2 :(得分:1)

您可以尝试此查询。 var 1 = jeff var 2 = Internal COUNT用于消除重复记录。

DISTINCT

答案 3 :(得分:0)

试试这个:

 select FK_ID,count(distinct TYPE_ID) from mytable
 where TYPE_ID<=3
 group by FK_ID
 having count(distinct TYPE_ID)=3

答案 4 :(得分:0)

您应该使用CTEDynamic传递值,这是您在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;

从上面SQL命令将产生结果(我已通过3):

ID  FK_ID   TYPE_ID
4   12      1
5   12      2
6   12      3