diff --git a/src/adapter/postgres.spec.ts b/src/adapter/postgres.spec.ts
index 70ab8478fe58c925df0a58714b09365d1b27a8e3..80167f09c0f07aeb46645ae8dd476ef32cb7e7e9 100644
--- a/src/adapter/postgres.spec.ts
+++ b/src/adapter/postgres.spec.ts
@@ -357,4 +357,23 @@ describe("postgres adapter", () => {
             done();
         });
     });
+
+    it("should get data from view when joins can be propagated", (done) => {
+        let view = adapterScenario.propagatedClauseView;
+        adapter.getDataFromView(view, (err, result) => {
+            expect(err).to.be.a("null");
+            expect(result).to.be.an("array");
+            expect(result).to.have.length(2);
+            expect(result[0]).to.be.an("object");
+            let keys: string[] = [];
+            keys = keys.concat(view.metrics.map((item) => item.name));
+            keys = keys.concat(view.dimensions.map((item) => item.name));
+            result.forEach((row) => {
+                expect(row).to.be.an("object");
+                expect(row).to.have.all.keys(keys);
+            });
+
+            done();
+        });
+    });
 });
diff --git a/src/adapter/postgres.ts b/src/adapter/postgres.ts
index 4b8d63fc5c9127de093df08c4ec9c284a18125cd..f2c7a3532b01168d01ab75540b3868fc815143a8 100644
--- a/src/adapter/postgres.ts
+++ b/src/adapter/postgres.ts
@@ -112,6 +112,7 @@ export class PostgresAdapter extends Adapter {
             Partial Join represents how many sources still exists,
             every join reduces this number.
         */
+        let clausesToCover = view.clauses.map((i) => i);
         while (partialJoin.length > 1) {
             /*
                 Variable map finds what dimenensions are still needed to
@@ -158,6 +159,17 @@ export class PostgresAdapter extends Adapter {
                 }
             }
 
+            /*
+                Also mark scores for dimensions inside clauses
+            */
+            for (let i = 0; i < clausesToCover.length; ++i) {
+                for (let j = 0; j < clausesToCover[i].targets.length; ++j) {
+                    if (map[clausesToCover[i].targets[j].name])  {
+                        ++map[clausesToCover[i].targets[j].name];
+                    }
+                }
+            }
+
             for (let i = 0; i < partialJoin.length; ++i) {
                 const dims = partialJoin[i].dimensions.filter((item) => {
                     return map[item.name] > 1;
@@ -171,13 +183,32 @@ export class PostgresAdapter extends Adapter {
                     again, with less dimensions, removing this dimension
                     from the view.
                 */
-                if (dims.length  < partialJoin[i].dimensions.length) {
+
+                let coveredClauses: Clause[] = [];
+                let notCoveredClauses: Clause[] = [];
+                /*
+                    If all dimensions in a clause are a sub set of the
+                    dimensions of a view, this clause is apllied now,
+                    propagating the clause to this point.
+
+                    Then this clause is removed from the set of clauses
+                */
+                for (let j = 0; j < clausesToCover.length; ++j) {
+                    if (clausesToCover[j].isCovered(partialJoin[i].dimensions)) {
+                        coveredClauses.push(clausesToCover[j]);
+                    }
+                    else {
+                        notCoveredClauses.push(clausesToCover[j]);
+                    }
+                }
+                clausesToCover = notCoveredClauses;
+                if (dims.length  < partialJoin[i].dimensions.length || coveredClauses.length > 0) {
                     const partial = new View({
                         metrics: partialJoin[i].metrics,
                         dimensions: dims,
                         keys: keys,
                         origin: false,
-                        clauses: partialJoin[i].clauses,
+                        clauses: coveredClauses.concat(partialJoin[i].clauses),
                         materialized: false
                     });
                     const from  = "(" +
diff --git a/src/core/clause.ts b/src/core/clause.ts
index 11a831dc55cc90349305958189d17d79175cecb0..8f61c5ddb2083a3399cb9cfc393cacf82a4b8511 100644
--- a/src/core/clause.ts
+++ b/src/core/clause.ts
@@ -20,6 +20,8 @@
 
 import { Filter } from "./filter";
 import { Hash } from "../util/hash";
+import { Dimension } from "./dimension";
+import { Metric } from "./metric";
 
 export interface ClauseOptions {
     filters: Filter[];
@@ -28,11 +30,29 @@ export interface ClauseOptions {
 export class Clause {
     public readonly id: string;
     public readonly filters: Filter[];
+    public readonly targets: (Metric|Dimension)[];
 
     constructor (options: ClauseOptions) {
-        this.filters = options.filters;
+        this.filters = options.filters.map((i) => i);
+        const t = this.filters.map((i) => i.target).sort((a, b) => {
+            return (a.name < b.name) ? -1 : 1;
+        });
+        if (t.length > 0) {
+            this.targets = [t[0]];
+            for (let i = 1; i < t.length; ++i) {
+                if (t[i - 1] !== t[i])  {
+                    this.targets.push(t[i]);
+                }
+            }
+        }
+        else {
+            this.targets = [];
+        }
         const filtersIds = this.filters.map((item) => item.id);
         this.id = Hash.sha1(filtersIds.sort());
     }
 
+    public isCovered(coverage: (Metric|Dimension)[]): boolean {
+        return coverage.every((i) => this.targets.some((j) => i.name === j.name));
+    }
 }
diff --git a/test/scenario.ts b/test/scenario.ts
index 856cc9ae37687beec4bb7c3b3a36260a4a0e92dc..946f1b7c33e4bf2c52dab0721adf3c1561d4e17c 100644
--- a/test/scenario.ts
+++ b/test/scenario.ts
@@ -54,6 +54,7 @@ interface AdapterScenario {
     notOriginCount: View;
     unMaterializebleView: View;
     partialJoinView: View;
+    propagatedClauseView: View;
 }
 
 interface DataCtrlScenario {
@@ -117,6 +118,11 @@ const filters: { [key: string]: Filter } = {
         operator: FilterOperator.NOTEQUAL,
         value: "1"
     }),
+    "dim:4" : new Filter({
+        target: dims[4],
+        operator: FilterOperator.NOTEQUAL,
+        value: "dim:4:1"
+    }),
     "dim:5" : new Filter({
         target: dims[5],
         operator: FilterOperator.NOTEQUAL,
@@ -137,6 +143,7 @@ const clauses: { [key: string]: Clause }  = {
     "view0le": new Clause({filters: [filters["dim:0:le"]]}),
     "view0dim0": new Clause({filters: [filters["dim:0:0"], filters["dim:0:1"]]}),
     "view9dim2": new Clause({filters: [filters["dim:2"]]}),
+    "view6dim4": new Clause({filters: [filters["dim:4"]]}),
     "view7dim5": new Clause({filters: [filters["dim:5"]]})
 };
 
@@ -348,6 +355,15 @@ const partialJoinView = new View({
     childViews: [views[3], views[5], views[6]]
 });
 
+const propagatedClauseView  = new View({
+    metrics: [mets[8]],
+    dimensions: [dims[4]],
+    materialized: false,
+    origin: false,
+    childViews: [views[6], views[7]],
+    clauses: [clauses.view7dim5, clauses.view6dim4]
+});
+
 export const engineScenario: EngineScenario = {
     metrics: mets,
     dimensions: dims,
@@ -374,7 +390,8 @@ export const adapterScenario: AdapterScenario = {
     notMatchFilterView: notMatchFilterView,
     notOriginCount: notOriginCount,
     unMaterializebleView: unMaterializebleView,
-    partialJoinView: partialJoinView
+    partialJoinView: partialJoinView,
+    propagatedClauseView: propagatedClauseView
 };
 
 export const dataCtrlScenario: DataCtrlScenario = {