2016-06-30 10 views
0

Ich habe folgende ModelleRails/SQL: Finden Sie Statistiken über eine belongs_to Beziehung

class Project 
    has_many :contributions 
end 

class Contributor 
    has_many :contributions 
end 

class Contribution 
    belongs_to :contributor 
    belongs_to :project 
end 

Ich versuche, wie viele Autoren in wie viele Projekte trugen zu finden und sortieren nach Anzahl der Projekte beigetragen.

Beispiel:

- Person 1 made contribution to Project 1 
- Person 1 made contribution to Project 2 
- Person 2 made contribution to Project 1 
- Person 2 made contribution to Project 3 
- Person 2 made contribution to Project 4 
- Person 3 made contribution to Project 4 
- Person 3 made contribution to Project 5 

In diesem Fall

- Person 1 made 2 contributions in 2 seperate projects. 
- Person 2 made 3 contributions in 3 seperate projects. 
- Person 3 made 2 contributions in 2 seperate projects. 

was bedeutet

- 2 people made 2 contributions 
- 1 person made 3 contributions 

Ergebnis ist: { 2 => 2, 1 => 3 }

Hier ist, was ich getan habe:

Dies gibt mir, wie viele Beiträge von jedem Mitarbeiter, aber nicht das, was ich suche.

Antwort

1

Try this:

Contributor.joins(:contributions).order("count(contributions.id) asc").group("contributor.id").count.group_by{|i| i.last}.map{|a| [a.last.count,a.first]} 
+0

Ist das für Sie nützlich? –

1
# First, you need to count the distinct contributions for every contributor 

contributors_info = Contributor.joins(:contributions).group("contributors.id").count("DISTINCT contributions.id") 

    (0.4ms) SELECT COUNT(DISTINCT contributions.id) AS count_distinct_contributions_id, contributors.id AS contributors_id FROM "contributors" INNER JOIN "contributions" ON "contributions"."contributor_id" = "contributors"."id" GROUP BY contributors.id 

=> {1=>2, 2=>3, 3=>2} 

Sie möchten Ihr Ergebnis so aussehen:

  • 2 Personen gemacht 2 Beiträge
  • 1 Person 3 Beiträge
  • Ergebnis aus ist: {2 => 2, 1 => 3}

Aber wenn es eine andere Person 4 Beiträge geleistet ist, wird Ihr Ergebnis wie: { 2 => 2, 1 => 3, 1 => 4 }, die keine gültige Hash ist. Das bedeutet, dass Sie die Ergebniskonstruktion ändern müssen. Ich schlage vor, dass Sie die contribution_count als Schlüssel verwenden und die Personen als Wert zählen, da contribution_count eindeutig ist.

# Then, use the previous information to get how many people made how many contributions 

contributors_info.reduce({}) do |result, (_, contribution_count)| 
    result[contribution_count] = (result[contribution_count] ||= 0) + 1 
    result 
end 

# two contributions => 2 people, three contributions => 1 person 
=> {2=>2, 3=>1} 
Verwandte Themen