diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
index 559e5964383c271fac2c59ef9ed1c4d72d8be43e..bcb8ea1b31a0cece38f2d631f2419d984d4ebb51 100644
--- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
+++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
@@ -1326,43 +1326,61 @@ public class CouchDBDao implements IDatabaseDao {
 
 	@Override
 	public int getLearningProgress(Session session) {
-		NovaView progressView = new NovaView("learning_progress/all");
-		progressView.setStartKeyArray(session.get_id());
-		progressView.setEndKeyArray(session.get_id(), "{}");
+		// Note: we have to use this many views because our CouchDB version does not support
+		// advanced features like summing over lists. Thus, we have to do it all by ourselves...
+		NovaView maximumValueView = new NovaView("learning_progress_maximum_value/max");
+		NovaView answerSumView = new NovaView("learning_progress_user_values/sum");
+		NovaView answerDocumentCountView = new NovaView("learning_progress_course_answers/count");
+		maximumValueView.setKey(session.get_id());
+		answerSumView.setStartKeyArray(session.get_id());
+		answerSumView.setEndKeyArray(session.get_id(), "{}");
+		answerDocumentCountView.setStartKeyArray(session.get_id());
+		answerDocumentCountView.setEndKeyArray(session.get_id(), "{}");
+		answerDocumentCountView.setGroup(true);
+
+		List<Document> maximumValueResult = this.getDatabase().view(maximumValueView).getResults();
+		List<Document> answerSumResult = this.getDatabase().view(answerSumView).getResults();
+		List<Document> answerDocumentCountResult = this.getDatabase().view(answerDocumentCountView).getResults();
+
+		if (maximumValueResult.isEmpty() || answerSumResult.isEmpty() || answerDocumentCountResult.isEmpty()) {
+			return 0;
+		}
 
-		List<Document> progressResults = this.getDatabase().view(progressView).getResults();
-		// when filtering just by session, the query contains all three values.
-		return getProgressPercentage(progressResults, progressResults);
+		final double courseMaximumValue = maximumValueResult.get(0).getInt("value");
+		final double userTotalValue = answerSumResult.get(0).getInt("value");
+		final double numUsers = answerDocumentCountResult.size();
+		if (courseMaximumValue == 0 || numUsers == 0) {
+			return 0;
+		}
+		final double courseAverageValue = userTotalValue / numUsers;
+		final double courseProgress = courseAverageValue / courseMaximumValue;
+		return (int)Math.round(courseProgress * 100);
 	}
 
 	@Override
 	public SimpleEntry<Integer,Integer> getMyLearningProgress(Session session, User user) {
-		NovaView progressView = new NovaView("learning_progress/all");
-		NovaView maximumView = new NovaView("learning_progress/all");
-		progressView.setKey(session.get_id(), user.getUsername());
-		maximumView.setStartKeyArray(session.get_id());
-		maximumView.setEndKeyArray(session.get_id(), "{}");
+		final int courseProgress = this.getLearningProgress(session);
 
-		List<Document> progressResults = this.getDatabase().view(progressView).getResults();
-		List<Document> maximumResults = this.getDatabase().view(maximumView).getResults();
+		NovaView maximumValueView = new NovaView("learning_progress_maximum_value/max");
+		NovaView answerSumView = new NovaView("learning_progress_user_values/sum");
+		maximumValueView.setKey(session.get_id());
+		answerSumView.setKey(session.get_id(), user.getUsername());
 
-		int myprogress = getProgressPercentage(progressResults, maximumResults);
-		int courseprogress = getProgressPercentage(maximumResults, maximumResults);
-		return new AbstractMap.SimpleEntry<Integer, Integer>(myprogress, courseprogress);
-	}
+		List<Document> maximumValueResult = this.getDatabase().view(maximumValueView).getResults();
+		List<Document> answerSumResult = this.getDatabase().view(answerSumView).getResults();
 
-	private int getProgressPercentage(List<Document> progressResults, List<Document> maximumResults) {
-		if (progressResults.isEmpty() || maximumResults.isEmpty()) {
-			return 0;
+		if (maximumValueResult.isEmpty() || answerSumResult.isEmpty()) {
+			return new AbstractMap.SimpleEntry<Integer, Integer>(0, courseProgress);
 		}
-		final int max = maximumResults.get(0).getJSONArray("value").getInt(0);
-		JSONArray values = progressResults.get(0).getJSONArray("value");
-		final int userResult = values.getInt(1);
-		final int numAnswers = values.getInt(2);
-		if (numAnswers == 0) {
-			return 0;
+
+		final double courseMaximumValue = maximumValueResult.get(0).getInt("value");
+		final double userTotalValue = answerSumResult.get(0).getInt("value");
+
+		if (courseMaximumValue == 0) {
+			return new AbstractMap.SimpleEntry<Integer, Integer>(0, courseProgress);
 		}
-		final int averageResult = userResult/numAnswers;
-		return (int)((averageResult * 100.0f) / max);
+		final double myProgress = userTotalValue / courseMaximumValue;
+
+		return new AbstractMap.SimpleEntry<Integer, Integer>((int)Math.round((myProgress*100)), courseProgress);
 	}
 }