2017-06-22 72 views
1

我正在为我插入到将用于多个挖掘任务的表中的事务记录刮取日志文件。每个记录都有(除其他外)一个ID和一个交易类型,无论是请求还是响应。请求/响应对将具有相同的ID。如何在单个表中查找不匹配的记录?

我的任务之一是找到所有没有相应响应的请求。我考虑将表加入自己,其中A.ID = B.ID和A.type ='req'和B.type ='res',但是这给我与我所需要的相反。

由于ID总是会出现一次或两次,是否有一个查询可以选择ID,而在表中只有一个ID出现?

+0

'SELECT * FROM the_table WHERE NOT EXISTS(SELECT * FROM the_table B where A.ID = B.ID AND A.type ='req'and B.type ='res');' – joop

回答

4

这是一种非常常见的查询类型。您可以尝试使用GROUP BY汇总表格中的ID值,然后保留仅显示一次的ID

SELECT ID 
FROM yourTable 
GROUP BY ID 
HAVING COUNT(*) = 1 

如果你也想回到那些ID整个记录中出现的唯一的一次,你可以试试这个:

SELECT t1.* 
FROM yourTable t1 
INNER JOIN 
(
    SELECT ID FROM yourTable GROUP BY ID HAVING COUNT(*) = 1 
) t2 
    ON t1.ID = t2.ID 
1

这会给你有要求的那些,但不respose

SELECT * 
FROM your_table A LEFT OUTER JOIN 
your_table B ON A.ID = B.ID 
AND A.type = 'req' and B.type = 'res' 
WHERE B.ID IS NULL 
+0

现在我正在显示我的SQL无知 - if加入A.ID = B.ID,那么B.ID如何可以为NULL并且A.ID不能为NULL? – Jim

+1

这是LEFT JOIN,您将在连接级别匹配A.ID = B.ID,因此如果有记录,WHERE语句将为false,并且不会选择该记录,因为它实际上具有type = req。但如果它没有type = req,那么将不会选择表B中的记录,这意味着B.ID为null – asmgx

+0

@Jim:这称为反连接。它主要用于直接方法存在问题的弱DBMS(即“NOT EXISTS”和“NOT IN”)。 –

2

直接的方法是NOT IN

select * 
from mytable 
where type = 'req' 
and id not in (select id from mytable where type = 'res'); 

你可以写出关于NOT EXISTS相同,但查询变得略少可读性:

select * 
from mytable req 
where type = 'req' 
and not exists (select * from mytable res where type = 'res' and res.id = req.id); 

再就是聚集的形式,你可以使用,例如:

select * 
from mytable 
where type = 'req' 
and id in 
(
    select id 
    from mytable 
    group by id 
    having count(case when type = 'res' then 1 end) = 0 
); 
相关问题