我有一个名为actions的表,其中包含以下列,我只想提取尚未执行某项操作的ID_tracking
。我试过了
SELECT id_tracking from table WHERE id_tracking NOT IN
( SELECT id_tracking FROM table where id_action = X ).
此方法有效,但在小型表上需要很长时间,并且会有数百万行的表,因此这不是解决方案。怎么办呢?
示例数据
ID_tracking | ID_action
1009 1
1009 2
1009 3
1009 5
1010 2
1010 3
1010 4
1011 5
答案 0 :(得分:0)
我经常使用GROUP BY
和HAVING
来解决此类问题:
SELECT id_tracking
FROM table t
GROUP BY id_tracking
HAVING SUM(id_action = x) = 0;
您的查询存在的一个问题是,您会为符合条件的每个id_tracking
获得多行。
但实际上,一种非常合理的方法是:
SELECT t.id_tracking
FROM tracking t
WHERE NOT EXISTS (SELECT 1
FROM trackingaction ta
WHERE ta.id_tracking = t.id_tracking AND
ta.id_action = X
);
这使用两个不同的表,一个表id_tracking
是唯一键,另一个表是您描述的表。为获得最佳效果,您需要trackingaction(id_tracking, id_action)
上的索引。
答案 1 :(得分:0)
使用distinct和join将使您的查询更快(当您在inner query
中获得大量结果时)。我只是使用了不同的并且翻译了你的不加入。试试这个
SELECT distinct yt.id_tracking
FROM table1 yt
left join (SELECT distinct id_tracking as idt from table1 where id_action = 3) mt
on yt.id_tracking=mt.idt
where mt.idt is null
答案 2 :(得分:0)
你为什么不这样做:
现在,您将不得不关心更新并将语句插入此跟踪ID表。因此,每当为跟踪ID添加操作时,如果ID_tracking存在与否,请检查此跟踪ID表。如果存在则更新does_it_have_action列等于1,否则使用does_it_have_action = 0插入它。
我希望这对你有用,一天你会有数十亿行。
P.S:这是新表tracking_ids的粗略结构
ID_tracking | does_it_have_action(默认为0)| created_at(当前 时间戳)