diff --git a/process/Sql_lib/process.js b/process/Sql_lib/process.js
index 18a3c8ebc2dd9f7dcb8560fed5f0e10b6b94ffe0..cfb5a109638a20414127ffd5e066d2356ccd774e 100644
--- a/process/Sql_lib/process.js
+++ b/process/Sql_lib/process.js
@@ -587,6 +587,250 @@ SqlCondition.equalsNot = function(pField, pValue, pAlternativeCond, pAlias) {
     return SqlCondition.begin(pAlias).andPrepare(pField, pValue, "# <> ?").build(pAlternativeCond);
 }
 
+
+/**
+ * Object for building sqls. The main purpose of this is to make it
+ * possible to use SqlCondition objects inside join conditions or sub sqls.
+ * This can also be useful to build complex sqls where parts should be added
+ * dynamically while keeping the code clear.
+ * 
+ * @class
+ */
+function SqlBuilder ()
+{
+    this._query = [];
+}
+
+/**
+ * Alternative way of creating a new SqlBuilder object that allows to use
+ * methods on it directly without having to put brackets around it
+ * 
+ * @return {SqlBuilder} a new SqlBuilder object
+ */
+SqlBuilder.begin = function ()
+{
+    return new SqlBuilder();
+}
+
+/**
+ * Builds the sql and uses db.translateStatement to make a string out of it.
+ * @return {String} the sql as string
+ */
+SqlBuilder.prototype.toString = function ()
+{
+    return db.translateStatement(this.build());
+}
+
+/**
+ * Adds a select clause to the sql.
+ * @param {String|String[]} pFields
+ * @return {SqlBuilder} current SqlBuilder object
+ */
+SqlBuilder.prototype.select = function (pFields)
+{
+    this._append(pFields, "select", true);
+    return this;
+}
+
+/**
+ * Adds a select distinct clause to the sql.
+ * @param {String|String[]} pFields
+ * @return {SqlBuilder} current SqlBuilder object
+ */
+SqlBuilder.prototype.selectDistinct = function (pFields)
+{
+    this._append(pFields, "select distinct", true);
+    return this;
+}
+
+/**
+ * Adds a from clause to the sql.
+ * @param {String} pTable
+ * @param {String} [pAlias] table alias
+ * @return {SqlBuilder} current SqlBuilder object
+ */
+SqlBuilder.prototype.from = function (pTable, pAlias)
+{
+    if (pAlias)
+        pTable += " " + pAlias;
+    this._append(pTable, "from");
+    return this;
+}
+
+/**
+ * Adds a join clause to the sql.
+ * @param {String} pTable
+ * @param {String|String[]} pCondition The where condition. This can be
+ *          a string (without the where keyword) or an array (for prepared queries).
+ * @param {String} [pAlias] table alias
+ * @return {SqlBuilder} current SqlBuilder object
+ */
+SqlBuilder.prototype.join = function (pTable, pCondition, pAlias)
+{
+    var joinStr = "join " + pTable;
+    if (pAlias)
+        joinStr += " " + pAlias;
+    this._append(joinStr + " on");
+    this._append(pCondition);
+    return this;
+}
+
+/**
+ * Adds a left join clause to the sql.
+ * @param {String} pTable
+ * @param {String|String[]} pCondition The where condition. This can be
+ *          a string (without the where keyword) or an array (for prepared queries).
+ * @param {String} [pAlias] table alias
+ * @return {SqlBuilder} current SqlBuilder object
+ */
+SqlBuilder.prototype.leftJoin = function (pTable, pCondition, pAlias)
+{
+    var joinStr = "left join " + pTable;
+    if (pAlias)
+        joinStr += " " + pAlias;
+    this._append(joinStr + " on");
+    this._append(pCondition);
+    return this;
+}
+
+/**
+ * Adds a where clause to the sql.
+ * 
+ * @param {String|String[]} pCondition The where condition. This can be
+ *          a string (without the where keyword) or an array (for prepared queries).
+ *          
+ * @return {SqlBuilder} current SqlBuilder object
+ */
+SqlBuilder.prototype.where = function (pCondition)
+{
+    this._append("where");
+    this._append(pCondition);
+    return this;
+}
+
+/**
+ * Adds a order by clause to the sql.
+ * @param {String} pOrderBy
+ * @return {SqlBuilder} current SqlBuilder object
+ */
+SqlBuilder.prototype.orderBy = function (pOrderBy)
+{
+    this._append(pOrderBy, "order by");
+    return this;
+}
+
+/**
+ * Adds another SqlBuilder object as a subquery.
+ * @param {SqlBuilder} pSubSelect
+ * @return {SqlBuilder} current SqlBuilder object
+ */
+SqlBuilder.prototype.subSelect = function (pSubSelect)
+{
+    this._append(pSubSelect);
+    return this;
+}
+
+/**
+ * Adds a group by clause to the sql.
+ * @param {String|String[]} pFields
+ * @return {SqlBuilder} current SqlBuilder object
+ */
+SqlBuilder.prototype.groupBy = function (pFields)
+{
+    this._append(pFields, "group by", true);
+    return this;
+}
+
+/**
+ * Adds another SqlBuilder object or select string with union.
+ * @param {SqlBuilder|String} pSelect
+ * @return {SqlBuilder} current SqlBuilder object
+ */
+SqlBuilder.prototype.union = function (pSelect)
+{
+    this._append("union");
+    this._append(pSelect);
+    return this;
+}
+
+/**
+ * Adds another SqlBuilder object or select string with union all.
+ * @param {SqlBuilder|String} pSelect
+ * @return {SqlBuilder} current SqlBuilder object
+ */
+SqlBuilder.prototype.unionAll = function (pSelect)
+{
+    this._append("union all");
+    this._append(pSelect);
+    return this;
+}
+
+/**
+ * Adds a having clause to the sql.
+ * 
+ * @param {String|String[]} pCondition The where condition. This can be
+ *          a string (without the where keyword) or an array (for prepared queries).
+ *          
+ * @return {SqlBuilder} current SqlBuilder object
+ */
+SqlBuilder.prototype.having = function (pCondition)
+{
+    this._append("having");
+    this._append(pCondition);
+    return this;
+}
+
+/**
+ * adds an element
+ * 
+ * @param {String|String[]|SqlBuilder} pElement the element to append
+ * @param {String} [pPrefix] string to be added before pElement
+ * @param {Boolean} [pAutoJoin] if this is true and pElement is an array, it will be automatically
+ *                               joined together to a string
+ * 
+ * @private
+ */
+SqlBuilder.prototype._append = function (pElement, pPrefix, pAutoJoin)
+{
+    if (pAutoJoin && pElement && typeof pElement !== "string" && pElement.length !== undefined)
+        pElement = pElement.join(", ");
+    if (pPrefix)
+        pElement = pPrefix + " " + pElement;
+    this._query.push(pPrefix + " " + pElement);
+}
+
+/**
+ * builds a prepared statement out of the object
+ * 
+ * @return {String[]} prepared statement
+ */
+SqlBuilder.prototype.build = function ()
+{
+    var sqlStr = "";
+    var preparedValues = [];
+    
+    for (let i = 0, l = this._query.length; i < l; i++)
+    {
+        let sqlPart = this._query[i];
+        if (sqlPart instanceof SqlBuilder)
+        {
+            let condition = sqlPart.build();
+            sqlPart = "(" + condition[0] + ")";
+            preparedValues = preparedValues.concat(condition[1]);
+        }
+        //array => prepared statement
+        else if (typeof pElement !== "string" && pElement.length === 2 && pElement[1].length !== undefined) 
+        {
+            preparedValues = preparedValues.concat(sqlPart[1]);
+            sqlPart = sqlPart[0];
+        }
+        sqlStr += " " + sqlPart;
+    }
+    return [sqlStr.trim(), preparedValues];
+}
+
+
+
 /**
  *provides functions for masking sql functions
  *