TSQL:仅当基于where子句存在1行时返回

时间:2016-05-03 18:30:16

标签: tsql

假设我有一个包含3列的表格,其中包含以下值:

   ticketid     indexid    type  
    ---          ---       ---
    100           191       0
    100           192       2
    100           193       4
    200           194       0
    300           195       1
    300           196       0

我想要的输出:

   ticketid     indexid    type  
    ---          ---       ---
    200           194       0

我只想要那些包含以下内容的行:

1)表中只有1行(基于ticketid)

2)有类型=(0,2,4)

这是我的查询无效:

select distinct ticketid from tab1 where type not in (1,3) group by ticketid having count(indexid) = 1

当我运行上述查询时,我仍然会收到超过1行的票证。我该如何解决这个问题?

4 个答案:

答案 0 :(得分:1)

您需要对数据进行分组并对每个组进行计数。对于前)

create table tab1 
(
    ticketid int,
    indexid int,
    type int
)



insert into tab1
values 
( 100,           191,       0),
(100,           192,       2),
(   100,           193 ,      4),
(  200  ,        194   ,    0),
( 300  ,         195 ,      1),
(300  ,         196  ,     0)




select * 
from tab1 


select ticketid 
from tab1 
--exclude tickets that contains the invalid types
where ticketID NOT IN (

    --get tickets that does not contain the valid types
    select ticketID
    from tab1
    where type NOT IN (0,2,4)
)
group by ticketid 
having count(1) = 1

答案 1 :(得分:1)

我已经编辑了这个答案,因为我误解了原来的要求。

DECLARE  @tab1 TABLE (TicketID INT, IndexID INT, Type Int)

INSERT 
  INTO   @tab1 (TicketID, IndexID, Type)
VALUES  (100,191,0)
       ,(100,192,2)
       ,(100,193,4)
       ,(200,194,0)
       ,(300,195,1)
       ,(300,196,0)


SELECT   T.TicketID
        ,T.IndexID
        ,T.Type
  FROM  (
         SELECT  TicketID
                ,COUNT(IndexID) AS CountOfIndex
                ,CASE WHEN Type IN (0,2,4) THEN 1 ELSE 0 END AS ValidType
           FROM  @tab1
          GROUP
             BY  TicketID
                ,CASE WHEN Type IN (0,2,4) THEN 1 ELSE 0 END 
        ) DATA1
  JOIN   @tab1 T
    ON   T.TicketID = DATA1.TicketID
 WHERE   DATA1.CountOfIndex = 1
GROUP BY T.TicketID
        ,T.IndexID
        ,T.Type
 HAVING MIN(DATA1.ValidType) = 1

这提供了以下结果:

TicketID    IndexID     Type
200         194         0

此查询使用派生表首先根据重复的TicketID值查找IndexID值的数量,同时还确定Type列值是否有效包含在最终输出中。

外部查询然后查找具有CountOfIndex = 1的票证,以及Type = 1的最小值(消除TicketID与无效的Type值相关联的任何记录)。

这可能不是最干净的解决方案,但我相信这段代码突出了对有意和无用数据进行分类的思考,以及如何过滤掉不需要的数据。

答案 2 :(得分:1)

假设ticketid+indexid是唯一的,您可以这样做:

select ticketid 
from tab1 
where type not in (1,3) 
group by ticketid 
having count(distinct indexid) = 1

(这是您重新格式化的原始查询,并将distinct关键字移至正确的位置)

答案 3 :(得分:1)

您可以在子查询中进行分组。然后在主查询中拉出所有列。

select ticketid, indexid, type
  from tab1
 where type in (0,2,4)
   and ticketid in (
    select ticketid from tab1 group by ticketid having count(*) = 1
)