2016-06-15 3 views
0

Ich habe zwei Tabellen mit Hattm-Beziehung (über eine Tabelle) verbunden.Gruppendatensätze für die Datenanalyse in Rails

Table1 
id : integer 
name: string 

Table2 
id : integer 
name: string 

Table3 
id  : integer 
table1_id: integer 
table2_id: integer 

Ich muss Tabelle1 Datensätze durch ähnliche Datensätze aus Tabelle2 gruppieren. Beispiel:

userx = Table1.create() 
user1.table2_ids = 3, 14, 15 
user2.table2_ids = 3, 14, 15, 16 
user3.table2_ids = 3, 14, 16 
user4.table2_ids = 2, 5, 7 
user5.table2_ids = 3, 5 

Ergebnis Gruppierung, die ich will, ist so etwas wie

=> [ [ [1,2], [3, 14, 15] ], [ [2,3], [3,14, 16] ], [ [ 1, 2, 3, 5], [3] ] ] 

Wo erste Array ist ein Benutzer-IDs zweite table2_ids ist. Ich habe da irgendeine SQL-Lösung oder muss ich irgendeine Art von Algorithmus erstellen?

Aktualisiert: Ok, ich habe einen Code, der funktioniert, wie ich gesagt habe. Vielleicht findet jemand, der mir helfen kann, es nützlich, meine Idee zu verstehen.

Aber ich kann wetten, dass Sie sich vorstellen können, wie lange es dauert, um mir eine Ausgabe zu zeigen. Für meine 500 Table1-Datensätze ist es in der Nähe von 1-2 Minuten. Wenn ich mehr haben werde, wird die Zeit im Fortschritt erhöht, also brauche ich eine elegante Lösung oder eine SQL-Abfrage.

Antwort

1

Die obigen Codes haben Leistungsproblem, dass Sie Datenbank N * N mal abfragen müssen, die bis zu einer einzigen Abfrage optimiert werden könnte.

# Query table3, constructing the data useful to us 
# { table1_id: [table2_ids], ... } 
records = Table3.all.group_by { |t| t.table1_id }.map { |t1_id, t3_records| 
    [t1_id, t3_records.map(&:table2_id)] 
    }.to_h 

Dann könnten Sie tun genau das Gleiche zu records das Endergebnis Hash zu bekommen.

UPDATE:

@AKovtunov Sie vermissen mich verstanden. Mein Code ist der erste Schritt. Mit records, die {t1_id: t2_ids} Hash haben, könnten Sie etw wie folgt tun:

hash = {} 
records.each do |t1_id, t2_ids| 
    records.each do |tt1_id, tt2_ids| 
    if t1_id != tt1_id 
     inter = t2_ids & tt2_ids 
     hash["#{t1_id}_#{tt1_id}"] = inter if !inter.empty? 
    end 
    end 
end 
+0

Es ist nicht das Gleiche. Ihr Code Hashes alles wie {t1_id: t3_records} Und meins zeigt ähnliche Datensätze für 2 t1 IDs. – AKovtunov

+0

Aber funktioniert wirklich schnell: D – AKovtunov

+0

@AKovtunov Du vermisst mich verstanden. Mein Code ist der erste Schritt. Mit 'records', die' {t1_id: t2_ids} 'hash haben, könntest du sowas tun: hash = {} records.each do | t1_id, t2_ids | records.each do | tt1_id, tt2_ids | wenn t1_id! = Tt1_id inter = t2_ids & tt2_ids hash ["# {t1_id} _ # {tt1_id}"] = inter wenn? Inter.empty? Ende Ende Ende –

Verwandte Themen