· 8 years ago · Mar 04, 2018, 08:20 AM
1ActiveRecord::Base.connection.execute(<<-SQL)
2 DROP TABLE IF EXISTS non_duplicate_brand_tuples;
3 CREATE TABLE non_duplicate_brand_tuples (
4 id serial primary key,
5 main_brand_id integer NOT NULL,
6 non_duplicate_brand_id integer NOT NULL
7 );
8SQL
9
10class NonDuplicateBrandTuples < ActiveRecord::Base
11end
12# Seeds
1320.downto(1).each_with_index do |first, second|
14 NonDuplicateBrandTuples.create main_brand_id: first, non_duplicate_brand_id: second
15end
16
17def sql_implementation
18 result =
19 NonDuplicateBrandTuples.connection.execute(<<~SQL)
20 WITH all_non_duplicates AS (
21 SELECT main_brand_id AS main, non_duplicate_brand_id AS non_duplicate
22 FROM non_duplicate_brand_tuples
23 UNION
24 SELECT non_duplicate_brand_id AS main, main_brand_id AS non_duplicate
25 FROM non_duplicate_brand_tuples
26 )
27 SELECT main, array_agg(non_duplicate) FROM all_non_duplicates GROUP BY main;
28 SQL
29
30 result.
31 values.
32 to_h.
33 transform_values { |v| PG::TextDecoder::Array.new.decode(v).map(&:to_i) }
34end
35
36def ruby_implementation
37 NonDuplicateBrandTuples.
38 pluck(:main_brand_id, :non_duplicate_brand_id).
39 map { |*tuple| tuple.sort }.
40 to_set
41end
42
43non_duplicates = sql_implementation
44# non_duplicates = ruby_implementation # Uncomment for using Ruby implementation
45duplicates = []
46
471.upto(100_000).each_with_index do |remote_brand_id, progress|
48 puts progress
49
50 1.upto(100).each do |brand_id|
51 next if non_duplicates[brand_id]&.include?(brand_id)
52 # next if non_duplicates.include? [remote_brand_id, brand_id].sort # Uncomment for using Ruby implementation
53
54 duplicates << [remote_brand_id, brand_id]
55 end
56end