Reputation: 7347
Lets say I have a table with 3 columns with following values:
ticketid indexid type
--- --- ---
100 191 0
100 192 2
100 193 4
200 194 0
300 195 1
300 196 0
My desired output:
ticketid indexid type
--- --- ---
200 194 0
I only want those rows which have:
1) only 1 row (based on ticketid) in the table
2) have type = (0,2,4)
This is the query I have which is not working:
select distinct ticketid from tab1 where type not in (1,3) group by ticketid having count(indexid) = 1
When I run the above query I am still getting tickets which have more than 1 rows. How can I fix this?
Upvotes: 2
Views: 4192
Reputation: 5458
You can do the grouping in a subquery. Then in the main query pull all of the columns.
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
)
Upvotes: 1
Reputation: 663
you need to group the data and do a count on each group. For ex)
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
Upvotes: 1
Reputation: 781
I've edited this answer because I misread the original requirements.
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
This provides the following results:
TicketID IndexID Type
200 194 0
This query uses a derived table to first find the number of IndexID values based on the repeating TicketID values, while also determining if the Type column value is valid for inclusion in the final output.
The outer query then looks for a the Tickets that have a CountOfIndex = 1, and the minimum value for the Type = 1 (eliminating any records where the TicketID was associated with an invalid Type value).
It may not be the cleanest solution, but I believe that this code highlights the thinking behind classifying wanted and unwanted data, and how to filter the unwanted data out.
Upvotes: 1
Reputation: 56725
Assuming that ticketid+indexid
is unique, you can do this:
select ticketid
from tab1
where type not in (1,3)
group by ticketid
having count(distinct indexid) = 1
(which is the just your original query reformatted and the distinct
keyword moved to the correct place)
Upvotes: 1