选择有差异的查询

时间:2017-04-05 11:13:29

标签: mysql sql select

我有一个名为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

3 个答案:

答案 0 :(得分:0)

我经常使用GROUP BYHAVING来解决此类问题:

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中获得大量结果时)。我只是使用了不同的并且翻译了你的不加入。试试这个

Demo At SqlFiddle

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_tracking?如果是,请在此处添加 does_it_have_action 列,以检查跟踪ID是否在操作表中添加了操作。
  • 当您使用ID_tracking和ID_action向表中添加新条目时,请更新该跟踪ID表并设置 does_it_have_action = 1 ,否则请将其保留为默认值0。
  • 如果要检查操作的跟踪ID,只需对此表进行选择查询。

现在,您将不得不关心更新并将语句插入此跟踪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(当前   时间戳)