0

I have the following Activity table:

ID      TYPE        SKU
=======================
1       create      ABC
2       create      DEF
3       destroy     DEF

How can I get all create events which DON'T have a destroy event?

Doing Activity.where(type: 'create') gives me ids 1 and 2.

But I only want the first row since id 2 also has a destroy event.

Hopstream
  • 6,391
  • 11
  • 50
  • 81

2 Answers2

3

I guess this should work

Activity.where('activities.type = ? AND activities.sku NOT IN
  (SELECT sku from activities where type = ?)', 'create', 'destroy')
Ju Liu
  • 3,939
  • 13
  • 18
1

IF you really want to use active record, this gets you closer:

class Activity < ActiveRecord::Base
  scope :with_destroy, lambda { where(:action => 'destroy') }
  scope :create, lambda {where(:action => 'create') }

  scope :create_without_destroy, lambda {
    create.where("sku not in (" << Activity.select(:sku).with_destroy.group(:sku).to_sql << ")")
  }

end

The generated SQL:

> Activity.create_without_destroy
SELECT "activities".* FROM "activities" 
WHERE "activities"."action" = 'create' AND (
  sku not in (
  SELECT 
    sku 
  FROM "activities" 
  WHERE "activities"."action" = 'destroy' 
  GROUP BY sku
))
John Naegle
  • 8,077
  • 3
  • 38
  • 47