diff --git a/.docs/examples/xps.md b/.docs/examples/xps-data.md
similarity index 94%
rename from .docs/examples/xps.md
rename to .docs/examples/xps-data.md
index 08abcd35bcf0eb4bf6aeb77dd8b859b002494fb3..539326347bbc6b3cce51f0733309399add6aa0fb 100644
--- a/.docs/examples/xps.md
+++ b/.docs/examples/xps-data.md
@@ -21,7 +21,7 @@ We read XPS data from the VAMAS-encoded format and inserted it into a
 that captures the VAMAS-schema. It can then be read using the [Python Library](../../api/python).
 
 <figure markdown>
-![Jupyter Notebook](../../images/screenshots/xps-jupyter.png){ .img-border }
+![Jupyter Notebook](../../images/screenshots/xps-chart.png){ .img-border }
 <figcaption>Figure 1: Jupyter Notebook accessing data on DBRepo using the Python Library.</figcaption>
 </figure>
 
@@ -44,4 +44,4 @@ we can visualize the ordinate values directly in the Jupyter Notebook.
 
 This work was part of a cooperation with the [Institute of Applied Physics](http://www.iap.tuwien.ac.at/).
 
-<img src="../../images/logos/iap.jpeg" width=100 />
\ No newline at end of file
+<img src="../../images/logos/iap.png" width=100 />
\ No newline at end of file
diff --git a/.docs/images/logos/iap.jpeg b/.docs/images/logos/iap.jpeg
deleted file mode 100644
index a2ed3957ff03ad1e1a2a7a8cae8c4186fb83fe60..0000000000000000000000000000000000000000
Binary files a/.docs/images/logos/iap.jpeg and /dev/null differ
diff --git a/.docs/images/logos/iap.png b/.docs/images/logos/iap.png
new file mode 100644
index 0000000000000000000000000000000000000000..763bd0580f2ffb49a283570717471d822ee7045c
Binary files /dev/null and b/.docs/images/logos/iap.png differ
diff --git a/.docs/images/screenshots/xps-chart.png b/.docs/images/screenshots/xps-chart.png
index 91768d7f7babe3c20a57fde415872ae268d45c73..b7b52a0805161779adb7cbcb6617c155702686e3 100644
Binary files a/.docs/images/screenshots/xps-chart.png and b/.docs/images/screenshots/xps-chart.png differ
diff --git a/.docs/images/screenshots/xps-jupyter.png b/.docs/images/screenshots/xps-jupyter.png
deleted file mode 100644
index 42fca0f1aefee23cf5cec257d593dd8c97df8ea0..0000000000000000000000000000000000000000
Binary files a/.docs/images/screenshots/xps-jupyter.png and /dev/null differ
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c74b4cabacbf60544fa005acb720440040173fcf..c7c0cfca0b6f44025bc8e597ed2030a7a291d41f 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -125,7 +125,7 @@ build-helm:
     - echo "$CI_REGISTRY_PASSWORD" | docker login --username "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY_URL
   script:
     - apk add sed helm curl
-    - helm package ./helm/dbrepo --sign --key 'Martin Weise' --keyring ./secring.gpg --destination ./build
+    - helm package ./helm/dbrepo --destination ./build
 
 verify-install-script:
   image: docker.io/docker:24-dind
diff --git a/dbrepo-analyse-service/Pipfile.lock b/dbrepo-analyse-service/Pipfile.lock
index 9a4ce182e44f3a2d2decb81b875d0ba268ab27ba..6c0b9b84473285b8085c9d1ca0b522c09afc16ff 100644
--- a/dbrepo-analyse-service/Pipfile.lock
+++ b/dbrepo-analyse-service/Pipfile.lock
@@ -167,19 +167,19 @@
         },
         "boto3": {
             "hashes": [
-                "sha256:7e8418b47dd43954a9088d504541bed8a42b6d06e712d02befba134c1c4d7c6d",
-                "sha256:7f676daef674fe74f34ce4063228eccc6e60c811f574720e31f230296c4bf29a"
+                "sha256:a7a696fd3e7f5f43a81450b441f3eb6c5a89d28efe867cd97d8fc73ea5d8c139",
+                "sha256:cc73de1c9d953b1f9da6ee2404af717e93d888f790f3e0291b22d1b8489eb401"
             ],
             "index": "pypi",
-            "version": "==1.34.126"
+            "version": "==1.34.129"
         },
         "botocore": {
             "hashes": [
-                "sha256:7a8ccb6a7c02456757a984a3a44331b6f51c94cb8b9b287cd045122fd177a4b0",
-                "sha256:7eff883c638fe30e0b036789df32d851e093d12544615a3b90062b42ac85bdbc"
+                "sha256:7c56e25af6112d69c5d14a15b42f76ba7687687abc463a96ac5edca19c0a9c2d",
+                "sha256:86d3dd30996aa459e9c3321edac12aebe47c73cb4acc7556941f9b4c39726088"
             ],
             "markers": "python_version >= '3.8'",
-            "version": "==1.34.126"
+            "version": "==1.34.129"
         },
         "certifi": {
             "hashes": [
@@ -887,45 +887,54 @@
         },
         "numpy": {
             "hashes": [
-                "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b",
-                "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818",
-                "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20",
-                "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0",
-                "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010",
-                "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a",
-                "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea",
-                "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c",
-                "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71",
-                "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110",
-                "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be",
-                "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a",
-                "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a",
-                "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5",
-                "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed",
-                "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd",
-                "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c",
-                "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e",
-                "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0",
-                "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c",
-                "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a",
-                "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b",
-                "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0",
-                "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6",
-                "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2",
-                "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a",
-                "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30",
-                "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218",
-                "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5",
-                "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07",
-                "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2",
-                "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4",
-                "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764",
-                "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef",
-                "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3",
-                "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"
+                "sha256:04494f6ec467ccb5369d1808570ae55f6ed9b5809d7f035059000a37b8d7e86f",
+                "sha256:0a43f0974d501842866cc83471bdb0116ba0dffdbaac33ec05e6afed5b615238",
+                "sha256:0e50842b2295ba8414c8c1d9d957083d5dfe9e16828b37de883f51fc53c4016f",
+                "sha256:0ec84b9ba0654f3b962802edc91424331f423dcf5d5f926676e0150789cb3d95",
+                "sha256:17067d097ed036636fa79f6a869ac26df7db1ba22039d962422506640314933a",
+                "sha256:1cde1753efe513705a0c6d28f5884e22bdc30438bf0085c5c486cdaff40cd67a",
+                "sha256:1e72728e7501a450288fc8e1f9ebc73d90cfd4671ebbd631f3e7857c39bd16f2",
+                "sha256:2635dbd200c2d6faf2ef9a0d04f0ecc6b13b3cad54f7c67c61155138835515d2",
+                "sha256:2ce46fd0b8a0c947ae047d222f7136fc4d55538741373107574271bc00e20e8f",
+                "sha256:34f003cb88b1ba38cb9a9a4a3161c1604973d7f9d5552c38bc2f04f829536609",
+                "sha256:354f373279768fa5a584bac997de6a6c9bc535c482592d7a813bb0c09be6c76f",
+                "sha256:38ecb5b0582cd125f67a629072fed6f83562d9dd04d7e03256c9829bdec027ad",
+                "sha256:3e8e01233d57639b2e30966c63d36fcea099d17c53bf424d77f088b0f4babd86",
+                "sha256:3f6bed7f840d44c08ebdb73b1825282b801799e325bcbdfa6bc5c370e5aecc65",
+                "sha256:4554eb96f0fd263041baf16cf0881b3f5dafae7a59b1049acb9540c4d57bc8cb",
+                "sha256:46e161722e0f619749d1cd892167039015b2c2817296104487cd03ed4a955995",
+                "sha256:49d9f7d256fbc804391a7f72d4a617302b1afac1112fac19b6c6cec63fe7fe8a",
+                "sha256:4d2f62e55a4cd9c58c1d9a1c9edaedcd857a73cb6fda875bf79093f9d9086f85",
+                "sha256:5f64641b42b2429f56ee08b4f427a4d2daf916ec59686061de751a55aafa22e4",
+                "sha256:63b92c512d9dbcc37f9d81b123dec99fdb318ba38c8059afc78086fe73820275",
+                "sha256:6d7696c615765091cc5093f76fd1fa069870304beaccfd58b5dcc69e55ef49c1",
+                "sha256:79e843d186c8fb1b102bef3e2bc35ef81160ffef3194646a7fdd6a73c6b97196",
+                "sha256:821eedb7165ead9eebdb569986968b541f9908979c2da8a4967ecac4439bae3d",
+                "sha256:84554fc53daa8f6abf8e8a66e076aff6ece62de68523d9f665f32d2fc50fd66e",
+                "sha256:8d83bb187fb647643bd56e1ae43f273c7f4dbcdf94550d7938cfc32566756514",
+                "sha256:903703372d46bce88b6920a0cd86c3ad82dae2dbef157b5fc01b70ea1cfc430f",
+                "sha256:9416a5c2e92ace094e9f0082c5fd473502c91651fb896bc17690d6fc475128d6",
+                "sha256:9a1712c015831da583b21c5bfe15e8684137097969c6d22e8316ba66b5baabe4",
+                "sha256:9c27f0946a3536403efb0e1c28def1ae6730a72cd0d5878db38824855e3afc44",
+                "sha256:a356364941fb0593bb899a1076b92dfa2029f6f5b8ba88a14fd0984aaf76d0df",
+                "sha256:a7039a136017eaa92c1848152827e1424701532ca8e8967fe480fe1569dae581",
+                "sha256:acd3a644e4807e73b4e1867b769fbf1ce8c5d80e7caaef0d90dcdc640dfc9787",
+                "sha256:ad0c86f3455fbd0de6c31a3056eb822fc939f81b1618f10ff3406971893b62a5",
+                "sha256:b4c76e3d4c56f145d41b7b6751255feefae92edbc9a61e1758a98204200f30fc",
+                "sha256:b6f6a8f45d0313db07d6d1d37bd0b112f887e1369758a5419c0370ba915b3871",
+                "sha256:c5a59996dc61835133b56a32ebe4ef3740ea5bc19b3983ac60cc32be5a665d54",
+                "sha256:c73aafd1afca80afecb22718f8700b40ac7cab927b8abab3c3e337d70e10e5a2",
+                "sha256:cee6cc0584f71adefe2c908856ccc98702baf95ff80092e4ca46061538a2ba98",
+                "sha256:cef04d068f5fb0518a77857953193b6bb94809a806bd0a14983a8f12ada060c9",
+                "sha256:cf5d1c9e6837f8af9f92b6bd3e86d513cdc11f60fd62185cc49ec7d1aba34864",
+                "sha256:e61155fae27570692ad1d327e81c6cf27d535a5d7ef97648a17d922224b216de",
+                "sha256:e7f387600d424f91576af20518334df3d97bc76a300a755f9a8d6e4f5cadd289",
+                "sha256:ed08d2703b5972ec736451b818c2eb9da80d66c3e84aed1deeb0c345fefe461b",
+                "sha256:fbd6acc766814ea6443628f4e6751d0da6593dae29c08c0b2606164db026970c",
+                "sha256:feff59f27338135776f6d4e2ec7aeeac5d5f7a08a83e80869121ef8164b74af9"
             ],
             "index": "pypi",
-            "version": "==1.26.4"
+            "version": "==2.0.0"
         },
         "opensearch-py": {
             "hashes": [
@@ -1400,11 +1409,11 @@
         },
         "urllib3": {
             "hashes": [
-                "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d",
-                "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"
+                "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472",
+                "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"
             ],
             "markers": "python_version >= '3.8'",
-            "version": "==2.2.1"
+            "version": "==2.2.2"
         },
         "werkzeug": {
             "hashes": [
@@ -1996,11 +2005,11 @@
         },
         "urllib3": {
             "hashes": [
-                "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d",
-                "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"
+                "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472",
+                "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"
             ],
             "markers": "python_version >= '3.8'",
-            "version": "==2.2.1"
+            "version": "==2.2.2"
         },
         "wrapt": {
             "hashes": [
diff --git a/dbrepo-analyse-service/lib/dbrepo-1.4.4-py3-none-any.whl b/dbrepo-analyse-service/lib/dbrepo-1.4.4-py3-none-any.whl
index 7e8fd7fca5aa6158bf57952f7f1050a08b331402..c47413901095398979c90dc1f41313ca044f7838 100644
Binary files a/dbrepo-analyse-service/lib/dbrepo-1.4.4-py3-none-any.whl and b/dbrepo-analyse-service/lib/dbrepo-1.4.4-py3-none-any.whl differ
diff --git a/dbrepo-analyse-service/lib/dbrepo-1.4.4.tar.gz b/dbrepo-analyse-service/lib/dbrepo-1.4.4.tar.gz
index 3e45d4513a31a1fda334ed9ad2c5cbad3803199a..8755a9707129705ca231b838235e0674a1d79da1 100644
Binary files a/dbrepo-analyse-service/lib/dbrepo-1.4.4.tar.gz and b/dbrepo-analyse-service/lib/dbrepo-1.4.4.tar.gz differ
diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SubsetServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SubsetServiceIntegrationTest.java
index aa30bc0580ff3b0aba950a1f1ea495b135280782..d13a37531b06e3572547b1f472e970ada78a7faa 100644
--- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SubsetServiceIntegrationTest.java
+++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SubsetServiceIntegrationTest.java
@@ -95,6 +95,35 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest {
         assertEquals(0.0, response.getResult().get(2).get("rainfall"));
     }
 
+    @Test
+    public void execute_joinWithAlias_succeeds() throws QueryStoreInsertException, TableMalformedException, SQLException,
+            QueryNotFoundException, InterruptedException, UserNotFoundException, NotAllowedException,
+            RemoteUnavailableException, ServiceException, DatabaseNotFoundException {
+
+        /* pre-condition */
+        Thread.sleep(1000) /* wait for test container some more */;
+
+        /* mock */
+        when(metadataServiceGateway.getUserById(QUERY_1_CREATED_BY))
+                .thenReturn(QUERY_1_CREATOR);
+
+        /* test */
+        final QueryResultDto response = queryService.execute(DATABASE_1_PRIVILEGED_DTO, QUERY_7_STATEMENT, Instant.now(), USER_1_ID, 0L, 10L, null, null);
+        assertNotNull(response);
+        assertNotNull(response.getId());
+        assertNotNull(response.getHeaders());
+        assertEquals(5, response.getHeaders().size());
+        assertEquals(List.of(Map.of("id", 0), Map.of("date", 1), Map.of("location", 2), Map.of("lat", 3), Map.of("lng", 4)), response.getHeaders());
+        assertNotNull(response.getResult());
+        assertEquals(1, response.getResult().size());
+        /* row 0 */
+        assertEquals(BigInteger.valueOf(1L), response.getResult().get(0).get("id"));
+        assertEquals(Instant.ofEpochSecond(1228089600), response.getResult().get(0).get("date"));
+        assertEquals("Albury", response.getResult().get(0).get("location"));
+        assertEquals(-36.0653583, response.getResult().get(0).get("lat"));
+        assertEquals(146.9112214, response.getResult().get(0).get("lng"));
+    }
+
     @Test
     public void execute_oneResult_succeeds() throws QueryStoreInsertException, TableMalformedException, SQLException,
             QueryNotFoundException, InterruptedException, UserNotFoundException, NotAllowedException,
diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java
index 163ec5940fb36d2a228f61a745773cbdea9f0a8f..2e95fc34d28fdcea292f6336717ff4be2c5c03f6 100644
--- a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java
+++ b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/DataMapper.java
@@ -29,6 +29,7 @@ import com.google.common.hash.Hashing;
 import net.sf.jsqlparser.JSQLParserException;
 import net.sf.jsqlparser.parser.CCJSqlParserManager;
 import net.sf.jsqlparser.schema.Column;
+import net.sf.jsqlparser.schema.Table;
 import net.sf.jsqlparser.statement.select.*;
 import org.jetbrains.annotations.NotNull;
 import org.mapstruct.Mapper;
@@ -273,51 +274,63 @@ public interface DataMapper {
                 }
             }
         }
-        final List<ColumnDto> allColumns = Stream.of(database.getViews()
-                                .stream()
-                                .map(ViewDto::getColumns)
-                                .flatMap(List::stream)
-                                .map(this::viewColumnDtoToColumnDto),
-                        database.getTables()
-                                .stream()
-                                .map(TableDto::getColumns)
-                                .flatMap(List::stream))
-                .flatMap(i -> i)
+        final List<ColumnDto> allColumns = database.getTables()
+                .stream()
+                .map(TableDto::getColumns)
+                .flatMap(List::stream)
                 .toList();
         log.trace("columns referenced in the from-clause and join-clause(s): {}", clauses);
         /* Checking if all columns exist */
         for (SelectItem clause : clauses) {
             final SelectExpressionItem item = (SelectExpressionItem) clause;
             final Column column = (Column) item.getExpression();
-            final Optional<net.sf.jsqlparser.schema.Table> optional = fromItems.stream()
-                    .map(t -> (net.sf.jsqlparser.schema.Table) t)
-                    .filter(t -> {
-                        if (column.getTable() == null) {
-                            /* column does not reference a specific table, so there is only one table */
-                            final String tableName = ((net.sf.jsqlparser.schema.Table) fromItems.get(0)).getName().replace("`", "");
-                            return tableMatches(t, tableName);
-                        }
-                        final String tableName = column.getTable().getName().replace("`", "");
-                        return tableMatches(t, tableName);
-                    })
-                    .findFirst();
-            if (optional.isEmpty()) {
-                log.error("Failed to find table/view {} (with designator {})", column.getTable().getName(), column.getTable().getAlias());
-                throw new JSQLParserException("Failed to find table/view " + column.getTable().getName() + " (with alias " + column.getTable().getAlias() + ")");
-            }
             final String columnName = column.getColumnName().replace("`", "");
-            final String tableOrView = optional.get().getName().replace("`", "");
             final List<ColumnDto> filteredColumns = allColumns.stream()
                     .filter(c -> (c.getAlias() != null && c.getAlias().equals(columnName)) || c.getInternalName().equals(columnName))
                     .toList();
-            final Optional<ColumnDto> optionalColumn = filteredColumns.stream()
-                    .filter(c -> columnMatches(c, tableOrView))
-                    .findFirst();
-            if (optionalColumn.isEmpty()) {
-                log.error("Failed to find column with name {} of table/view {} in {}", columnName, tableOrView, filteredColumns.stream().map(c -> c.getTable().getInternalName() + "." + c.getInternalName()).toList());
-                throw new JSQLParserException("Failed to find column with name " + columnName + " of table/view " + tableOrView);
+            String tableOrView = null;
+            for (Table t : fromItems.stream().map(t -> (net.sf.jsqlparser.schema.Table) t).toList()) {
+                if (column.getTable() == null) {
+                    /* column does not reference a specific table, find out */
+                    final List<String> filteredTables = filteredColumns.stream()
+                            .map(c -> c.getTable().getInternalName())
+                            .filter(table -> fromItems.stream().map(f -> (Table) f).anyMatch(otherTable -> otherTable.getName().replace("`", "").equals(table)))
+                            .toList();
+                    if (filteredTables.size() != 1) {
+                        log.error("Failed to filter column {} to exactly one match: {}", columnName, filteredTables.stream().map(table -> table + "." + columnName).toList());
+                        throw new JSQLParserException("Failed to filter column " + columnName + " to exactly one match");
+                    }
+                    if (tableMatches(t, filteredTables.get(0))) {
+                        tableOrView = t.getName().replace("`", "");
+                        break;
+                    }
+                }
+                /* column references a specific table */
+                final String tableOrAlias = (t.getAlias() != null ? t.getAlias().getName() : column.getTable().getName())
+                        .replace("`", "");
+                if (tableMatches(t, tableOrAlias)) {
+                    tableOrView = t.getName().replace("`", "");
+                    break;
+                }
+            }
+            if (tableOrView == null) {
+                log.error("Failed to find table/view {} (with designator {})", column.getTable().getName(), column.getTable().getAlias());
+                throw new JSQLParserException("Failed to find table/view " + column.getTable().getName() + " (with alias " + column.getTable().getAlias() + ")");
+            }
+            final String finalTableOrView = tableOrView;
+            final List<ColumnDto> selectColumns = filteredColumns.stream()
+                    .filter(c -> c.getTable().getInternalName().equals(finalTableOrView))
+                    .toList();
+            final ColumnDto resultColumn;
+            if (selectColumns.size() != 1) {
+                if (filteredColumns.size() != 1) {
+                    log.error("Failed to filter column {} to exactly one match: {}", columnName, selectColumns.stream().map(c -> c.getTable().getInternalName() + "." + c.getInternalName()).toList());
+                    throw new JSQLParserException("Failed to filter column " + columnName + " to exactly one match");
+                }
+                resultColumn = filteredColumns.get(0);
+            } else {
+                resultColumn = selectColumns.get(0);
             }
-            final ColumnDto resultColumn = optionalColumn.get();
             if (item.getAlias() != null) {
                 resultColumn.setAlias(item.getAlias().getName().replace("`", ""));
             }
@@ -330,14 +343,14 @@ public interface DataMapper {
         return columns;
     }
 
-    default boolean tableMatches(net.sf.jsqlparser.schema.Table table, String otherTableName) {
+    default boolean tableMatches(net.sf.jsqlparser.schema.Table table, String tableOrDesignator) {
         final String tableName = table.getName()
                 .trim()
                 .replace("`", "");
         if (table.getAlias() == null) {
             /* table does not have designator */
             log.trace("table '{}' has no designator", tableName);
-            return tableName.equals(otherTableName);
+            return tableName.equals(tableOrDesignator);
         }
         /* has designator */
         final String designator = table.getAlias()
@@ -345,26 +358,7 @@ public interface DataMapper {
                 .trim()
                 .replace("`", "");
         log.trace("table '{}' has designator {}", tableName, designator);
-        return designator.equals(otherTableName);
-    }
-
-    default boolean columnMatches(ColumnDto column, String tableOrView) {
-        if (column.getTable() != null && column.getTable().getInternalName().equals(tableOrView)) {
-            log.trace("table '{}' found in column table", tableOrView);
-            return true;
-        }
-        if (column.getViews() == null) {
-            log.trace("table/view '{}' not found among column views: empty list", tableOrView);
-            return false;
-        }
-        /* maybe matches one of the other views */
-        final boolean found = column.getViews()
-                .stream()
-                .anyMatch(v -> v.getInternalName().equals(tableOrView));
-        if (!found) {
-            log.trace("table/view '{}' not found among column views: {}", tableOrView, column.getViews().stream().map(ViewDto::getInternalName).toList());
-        }
-        return found;
+        return designator.equals(tableOrDesignator);
     }
 
     default List<FromItem> fromItemToFromItems(FromItem data) throws JSQLParserException {
diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/TableDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/TableDto.java
index 5764b311cacdd773e1e071718c2caf6db65977a7..a512cf8010195e5c107f35d8d2756251460bca62 100644
--- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/TableDto.java
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/TableDto.java
@@ -25,6 +25,7 @@ import java.util.UUID;
 @AllArgsConstructor
 @Jacksonized
 @ToString
+@EqualsAndHashCode(onlyExplicitlyIncluded = true)
 public class TableDto {
 
     @NotNull
@@ -32,6 +33,7 @@ public class TableDto {
 
     @NotNull
     @JsonProperty("database_id")
+    @EqualsAndHashCode.Include
     private Long tdbid;
 
     @NotBlank
@@ -41,6 +43,7 @@ public class TableDto {
     @NotBlank
     @JsonProperty("internal_name")
     @Schema(example = "air_quality")
+    @EqualsAndHashCode.Include
     private String internalName;
 
     @Schema
diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnDto.java
index 026d5d89b7dbb77a6bf4cd94b60448f8a73bc424..a506dbca82e9e64d4a0cec4fec12640452f56456 100644
--- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnDto.java
+++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnDto.java
@@ -25,6 +25,7 @@ import java.util.List;
 @AllArgsConstructor
 @Jacksonized
 @ToString
+@EqualsAndHashCode(onlyExplicitlyIncluded = true)
 public class ColumnDto {
 
     @NotNull
@@ -52,6 +53,7 @@ public class ColumnDto {
     @Size(max = 64)
     @JsonProperty("internal_name")
     @Schema(example = "mdb_date")
+    @EqualsAndHashCode.Include
     private String internalName;
 
     @Schema
@@ -122,6 +124,7 @@ public class ColumnDto {
 
     @ToString.Exclude
     @JsonIgnore
+    @EqualsAndHashCode.Include
     private TableDto table;
 
     @ToString.Exclude
diff --git a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java
index 2d9a2f40a03a60b4650e8fa626d9ef17e7ab9eb4..1b3bd7cd0055a0c4c9cbd699f85fccddcf5e43b5 100644
--- a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java
+++ b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java
@@ -2602,6 +2602,8 @@ public abstract class BaseTest {
             .resultNumber(2L)
             .build();
 
+    public final static String QUERY_7_STATEMENT = "SELECT id, date, a.location, lat, lng FROM weather_aus a JOIN weather_location l on a.location = l.location WHERE date = '2008-12-01'";
+
     public final static Long QUERY_4_ID = 4L;
     public final static String QUERY_4_STATEMENT = "SELECT `id`, `value` FROM `mfcc`";
     public final static String QUERY_4_QUERY_HASH = "df7da3801dfb5c191ff6711d79ce6455f3c09ec8323ce1ff7208ab85387263f5";
diff --git a/dbrepo-search-service/Pipfile.lock b/dbrepo-search-service/Pipfile.lock
index 7117575adf21fb3bc4458a54cbb57c49c3e732ee..0ffce7c2f6e2888f0e4810affeb0ef24ddccb584 100644
--- a/dbrepo-search-service/Pipfile.lock
+++ b/dbrepo-search-service/Pipfile.lock
@@ -551,7 +551,7 @@
                 "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da",
                 "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"
             ],
-            "markers": "platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))",
+            "markers": "python_version < '3.13' and platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))",
             "version": "==3.0.3"
         },
         "gunicorn": {
@@ -796,45 +796,54 @@
         },
         "numpy": {
             "hashes": [
-                "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b",
-                "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818",
-                "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20",
-                "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0",
-                "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010",
-                "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a",
-                "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea",
-                "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c",
-                "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71",
-                "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110",
-                "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be",
-                "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a",
-                "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a",
-                "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5",
-                "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed",
-                "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd",
-                "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c",
-                "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e",
-                "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0",
-                "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c",
-                "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a",
-                "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b",
-                "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0",
-                "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6",
-                "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2",
-                "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a",
-                "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30",
-                "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218",
-                "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5",
-                "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07",
-                "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2",
-                "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4",
-                "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764",
-                "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef",
-                "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3",
-                "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"
+                "sha256:04494f6ec467ccb5369d1808570ae55f6ed9b5809d7f035059000a37b8d7e86f",
+                "sha256:0a43f0974d501842866cc83471bdb0116ba0dffdbaac33ec05e6afed5b615238",
+                "sha256:0e50842b2295ba8414c8c1d9d957083d5dfe9e16828b37de883f51fc53c4016f",
+                "sha256:0ec84b9ba0654f3b962802edc91424331f423dcf5d5f926676e0150789cb3d95",
+                "sha256:17067d097ed036636fa79f6a869ac26df7db1ba22039d962422506640314933a",
+                "sha256:1cde1753efe513705a0c6d28f5884e22bdc30438bf0085c5c486cdaff40cd67a",
+                "sha256:1e72728e7501a450288fc8e1f9ebc73d90cfd4671ebbd631f3e7857c39bd16f2",
+                "sha256:2635dbd200c2d6faf2ef9a0d04f0ecc6b13b3cad54f7c67c61155138835515d2",
+                "sha256:2ce46fd0b8a0c947ae047d222f7136fc4d55538741373107574271bc00e20e8f",
+                "sha256:34f003cb88b1ba38cb9a9a4a3161c1604973d7f9d5552c38bc2f04f829536609",
+                "sha256:354f373279768fa5a584bac997de6a6c9bc535c482592d7a813bb0c09be6c76f",
+                "sha256:38ecb5b0582cd125f67a629072fed6f83562d9dd04d7e03256c9829bdec027ad",
+                "sha256:3e8e01233d57639b2e30966c63d36fcea099d17c53bf424d77f088b0f4babd86",
+                "sha256:3f6bed7f840d44c08ebdb73b1825282b801799e325bcbdfa6bc5c370e5aecc65",
+                "sha256:4554eb96f0fd263041baf16cf0881b3f5dafae7a59b1049acb9540c4d57bc8cb",
+                "sha256:46e161722e0f619749d1cd892167039015b2c2817296104487cd03ed4a955995",
+                "sha256:49d9f7d256fbc804391a7f72d4a617302b1afac1112fac19b6c6cec63fe7fe8a",
+                "sha256:4d2f62e55a4cd9c58c1d9a1c9edaedcd857a73cb6fda875bf79093f9d9086f85",
+                "sha256:5f64641b42b2429f56ee08b4f427a4d2daf916ec59686061de751a55aafa22e4",
+                "sha256:63b92c512d9dbcc37f9d81b123dec99fdb318ba38c8059afc78086fe73820275",
+                "sha256:6d7696c615765091cc5093f76fd1fa069870304beaccfd58b5dcc69e55ef49c1",
+                "sha256:79e843d186c8fb1b102bef3e2bc35ef81160ffef3194646a7fdd6a73c6b97196",
+                "sha256:821eedb7165ead9eebdb569986968b541f9908979c2da8a4967ecac4439bae3d",
+                "sha256:84554fc53daa8f6abf8e8a66e076aff6ece62de68523d9f665f32d2fc50fd66e",
+                "sha256:8d83bb187fb647643bd56e1ae43f273c7f4dbcdf94550d7938cfc32566756514",
+                "sha256:903703372d46bce88b6920a0cd86c3ad82dae2dbef157b5fc01b70ea1cfc430f",
+                "sha256:9416a5c2e92ace094e9f0082c5fd473502c91651fb896bc17690d6fc475128d6",
+                "sha256:9a1712c015831da583b21c5bfe15e8684137097969c6d22e8316ba66b5baabe4",
+                "sha256:9c27f0946a3536403efb0e1c28def1ae6730a72cd0d5878db38824855e3afc44",
+                "sha256:a356364941fb0593bb899a1076b92dfa2029f6f5b8ba88a14fd0984aaf76d0df",
+                "sha256:a7039a136017eaa92c1848152827e1424701532ca8e8967fe480fe1569dae581",
+                "sha256:acd3a644e4807e73b4e1867b769fbf1ce8c5d80e7caaef0d90dcdc640dfc9787",
+                "sha256:ad0c86f3455fbd0de6c31a3056eb822fc939f81b1618f10ff3406971893b62a5",
+                "sha256:b4c76e3d4c56f145d41b7b6751255feefae92edbc9a61e1758a98204200f30fc",
+                "sha256:b6f6a8f45d0313db07d6d1d37bd0b112f887e1369758a5419c0370ba915b3871",
+                "sha256:c5a59996dc61835133b56a32ebe4ef3740ea5bc19b3983ac60cc32be5a665d54",
+                "sha256:c73aafd1afca80afecb22718f8700b40ac7cab927b8abab3c3e337d70e10e5a2",
+                "sha256:cee6cc0584f71adefe2c908856ccc98702baf95ff80092e4ca46061538a2ba98",
+                "sha256:cef04d068f5fb0518a77857953193b6bb94809a806bd0a14983a8f12ada060c9",
+                "sha256:cf5d1c9e6837f8af9f92b6bd3e86d513cdc11f60fd62185cc49ec7d1aba34864",
+                "sha256:e61155fae27570692ad1d327e81c6cf27d535a5d7ef97648a17d922224b216de",
+                "sha256:e7f387600d424f91576af20518334df3d97bc76a300a755f9a8d6e4f5cadd289",
+                "sha256:ed08d2703b5972ec736451b818c2eb9da80d66c3e84aed1deeb0c345fefe461b",
+                "sha256:fbd6acc766814ea6443628f4e6751d0da6593dae29c08c0b2606164db026970c",
+                "sha256:feff59f27338135776f6d4e2ec7aeeac5d5f7a08a83e80869121ef8164b74af9"
             ],
             "markers": "python_version == '3.11'",
-            "version": "==1.26.4"
+            "version": "==2.0.0"
         },
         "opensearch-py": {
             "hashes": [
@@ -1263,58 +1272,58 @@
         },
         "sqlalchemy": {
             "hashes": [
-                "sha256:0094c5dc698a5f78d3d1539853e8ecec02516b62b8223c970c86d44e7a80f6c7",
-                "sha256:0138c5c16be3600923fa2169532205d18891b28afa817cb49b50e08f62198bb8",
-                "sha256:0a089e218654e740a41388893e090d2e2c22c29028c9d1353feb38638820bbeb",
-                "sha256:0b3f4c438e37d22b83e640f825ef0f37b95db9aa2d68203f2c9549375d0b2260",
-                "sha256:16863e2b132b761891d6c49f0a0f70030e0bcac4fd208117f6b7e053e68668d0",
-                "sha256:1f9a727312ff6ad5248a4367358e2cf7e625e98b1028b1d7ab7b806b7d757513",
-                "sha256:2383146973a15435e4717f94c7509982770e3e54974c71f76500a0136f22810b",
-                "sha256:2753743c2afd061bb95a61a51bbb6a1a11ac1c44292fad898f10c9839a7f75b2",
-                "sha256:296230899df0b77dec4eb799bcea6fbe39a43707ce7bb166519c97b583cfcab3",
-                "sha256:2a4f4da89c74435f2bc61878cd08f3646b699e7d2eba97144030d1be44e27584",
-                "sha256:2b1708916730f4830bc69d6f49d37f7698b5bd7530aca7f04f785f8849e95255",
-                "sha256:2ecabd9ccaa6e914e3dbb2aa46b76dede7eadc8cbf1b8083c94d936bcd5ffb49",
-                "sha256:311710f9a2ee235f1403537b10c7687214bb1f2b9ebb52702c5aa4a77f0b3af7",
-                "sha256:37a4b4fb0dd4d2669070fb05b8b8824afd0af57587393015baee1cf9890242d9",
-                "sha256:3a365eda439b7a00732638f11072907c1bc8e351c7665e7e5da91b169af794af",
-                "sha256:3b48154678e76445c7ded1896715ce05319f74b1e73cf82d4f8b59b46e9c0ddc",
-                "sha256:3b69e934f0f2b677ec111b4d83f92dc1a3210a779f69bf905273192cf4ed433e",
-                "sha256:3cb5a646930c5123f8461f6468901573f334c2c63c795b9af350063a736d0134",
-                "sha256:408f8b0e2c04677e9c93f40eef3ab22f550fecb3011b187f66a096395ff3d9fd",
-                "sha256:40ad017c672c00b9b663fcfcd5f0864a0a97828e2ee7ab0c140dc84058d194cf",
-                "sha256:5a79d65395ac5e6b0c2890935bad892eabb911c4aa8e8015067ddb37eea3d56c",
-                "sha256:5a8e3b0a7e09e94be7510d1661339d6b52daf202ed2f5b1f9f48ea34ee6f2d57",
-                "sha256:69c9db1ce00e59e8dd09d7bae852a9add716efdc070a3e2068377e6ff0d6fdaa",
-                "sha256:7108d569d3990c71e26a42f60474b4c02c8586c4681af5fd67e51a044fdea86a",
-                "sha256:77d2edb1f54aff37e3318f611637171e8ec71472f1fdc7348b41dcb226f93d90",
-                "sha256:7d74336c65705b986d12a7e337ba27ab2b9d819993851b140efdf029248e818e",
-                "sha256:8409de825f2c3b62ab15788635ccaec0c881c3f12a8af2b12ae4910a0a9aeef6",
-                "sha256:955991a09f0992c68a499791a753523f50f71a6885531568404fa0f231832aa0",
-                "sha256:99650e9f4cf3ad0d409fed3eec4f071fadd032e9a5edc7270cd646a26446feeb",
-                "sha256:9a5baf9267b752390252889f0c802ea13b52dfee5e369527da229189b8bd592e",
-                "sha256:a0ef36b28534f2a5771191be6edb44cc2673c7b2edf6deac6562400288664221",
-                "sha256:a1429a4b0f709f19ff3b0cf13675b2b9bfa8a7e79990003207a011c0db880a13",
-                "sha256:a7bfc726d167f425d4c16269a9a10fe8630ff6d14b683d588044dcef2d0f6be7",
-                "sha256:a943d297126c9230719c27fcbbeab57ecd5d15b0bd6bfd26e91bfcfe64220621",
-                "sha256:ae8c62fe2480dd61c532ccafdbce9b29dacc126fe8be0d9a927ca3e699b9491a",
-                "sha256:b60203c63e8f984df92035610c5fb76d941254cf5d19751faab7d33b21e5ddc0",
-                "sha256:b6bf767d14b77f6a18b6982cbbf29d71bede087edae495d11ab358280f304d8e",
-                "sha256:b6c7ec2b1f4969fc19b65b7059ed00497e25f54069407a8701091beb69e591a5",
-                "sha256:bba002a9447b291548e8d66fd8c96a6a7ed4f2def0bb155f4f0a1309fd2735d5",
-                "sha256:bc0c53579650a891f9b83fa3cecd4e00218e071d0ba00c4890f5be0c34887ed3",
-                "sha256:c4f61ada6979223013d9ab83a3ed003ded6959eae37d0d685db2c147e9143797",
-                "sha256:c62d401223f468eb4da32627bffc0c78ed516b03bb8a34a58be54d618b74d472",
-                "sha256:e42203d8d20dc704604862977b1470a122e4892791fe3ed165f041e4bf447a1b",
-                "sha256:edc16a50f5e1b7a06a2dcc1f2205b0b961074c123ed17ebda726f376a5ab0953",
-                "sha256:efedba7e13aa9a6c8407c48facfdfa108a5a4128e35f4c68f20c3407e4376aa9",
-                "sha256:f1dc3eabd8c0232ee8387fbe03e0a62220a6f089e278b1f0aaf5e2d6210741ad",
-                "sha256:f69e4c756ee2686767eb80f94c0125c8b0a0b87ede03eacc5c8ae3b54b99dc46",
-                "sha256:f7703c2010355dd28f53deb644a05fc30f796bd8598b43f0ba678878780b6e4c",
-                "sha256:fa561138a64f949f3e889eb9ab8c58e1504ab351d6cf55259dc4c248eaa19da6"
+                "sha256:0b0f658414ee4e4b8cbcd4a9bb0fd743c5eeb81fc858ca517217a8013d282c96",
+                "sha256:2196208432deebdfe3b22185d46b08f00ac9d7b01284e168c212919891289396",
+                "sha256:23b9fbb2f5dd9e630db70fbe47d963c7779e9c81830869bd7d137c2dc1ad05fb",
+                "sha256:26a6a9837589c42b16693cf7bf836f5d42218f44d198f9343dd71d3164ceeeac",
+                "sha256:2a21c97efcbb9f255d5c12a96ae14da873233597dfd00a3a0c4ce5b3e5e79704",
+                "sha256:2e2c38c2a4c5c634fe6c3c58a789712719fa1bf9b9d6ff5ebfce9a9e5b89c1ca",
+                "sha256:2fc47dc6185a83c8100b37acda27658fe4dbd33b7d5e7324111f6521008ab4fe",
+                "sha256:2fd17e3bb8058359fa61248c52c7b09a97cf3c820e54207a50af529876451808",
+                "sha256:352b2770097f41bff6029b280c0e03b217c2dcaddc40726f8f53ed58d8a85da4",
+                "sha256:3b74570d99126992d4b0f91fb87c586a574a5872651185de8297c6f90055ae42",
+                "sha256:3cb8a66b167b033ec72c3812ffc8441d4e9f5f78f5e31e54dcd4c90a4ca5bebc",
+                "sha256:3f9faef422cfbb8fd53716cd14ba95e2ef655400235c3dfad1b5f467ba179c8c",
+                "sha256:4b600e9a212ed59355813becbcf282cfda5c93678e15c25a0ef896b354423238",
+                "sha256:501ff052229cb79dd4c49c402f6cb03b5a40ae4771efc8bb2bfac9f6c3d3508f",
+                "sha256:56d51ae825d20d604583f82c9527d285e9e6d14f9a5516463d9705dab20c3740",
+                "sha256:597fec37c382a5442ffd471f66ce12d07d91b281fd474289356b1a0041bdf31d",
+                "sha256:5a48ac4d359f058474fadc2115f78a5cdac9988d4f99eae44917f36aa1476327",
+                "sha256:5b6cf796d9fcc9b37011d3f9936189b3c8074a02a4ed0c0fbbc126772c31a6d4",
+                "sha256:66f63278db425838b3c2b1c596654b31939427016ba030e951b292e32b99553e",
+                "sha256:69f3e3c08867a8e4856e92d7afb618b95cdee18e0bc1647b77599722c9a28911",
+                "sha256:6e2622844551945db81c26a02f27d94145b561f9d4b0c39ce7bfd2fda5776dac",
+                "sha256:6f77c4f042ad493cb8595e2f503c7a4fe44cd7bd59c7582fd6d78d7e7b8ec52c",
+                "sha256:74afabeeff415e35525bf7a4ecdab015f00e06456166a2eba7590e49f8db940e",
+                "sha256:750900a471d39a7eeba57580b11983030517a1f512c2cb287d5ad0fcf3aebd58",
+                "sha256:78fe11dbe37d92667c2c6e74379f75746dc947ee505555a0197cfba9a6d4f1a4",
+                "sha256:79a40771363c5e9f3a77f0e28b3302801db08040928146e6808b5b7a40749c88",
+                "sha256:7bd112be780928c7f493c1a192cd8c5fc2a2a7b52b790bc5a84203fb4381c6be",
+                "sha256:8a41514c1a779e2aa9a19f67aaadeb5cbddf0b2b508843fcd7bafdf4c6864005",
+                "sha256:9f2bee229715b6366f86a95d497c347c22ddffa2c7c96143b59a2aa5cc9eebbc",
+                "sha256:9fea3d0884e82d1e33226935dac990b967bef21315cbcc894605db3441347443",
+                "sha256:afb6dde6c11ea4525318e279cd93c8734b795ac8bb5dda0eedd9ebaca7fa23f1",
+                "sha256:b607489dd4a54de56984a0c7656247504bd5523d9d0ba799aef59d4add009484",
+                "sha256:b6e22630e89f0e8c12332b2b4c282cb01cf4da0d26795b7eae16702a608e7ca1",
+                "sha256:b9c01990d9015df2c6f818aa8f4297d42ee71c9502026bb074e713d496e26b67",
+                "sha256:bd15026f77420eb2b324dcb93551ad9c5f22fab2c150c286ef1dc1160f110203",
+                "sha256:c06fb43a51ccdff3b4006aafee9fcf15f63f23c580675f7734245ceb6b6a9e05",
+                "sha256:c76c81c52e1e08f12f4b6a07af2b96b9b15ea67ccdd40ae17019f1c373faa227",
+                "sha256:ccaf1b0c90435b6e430f5dd30a5aede4764942a695552eb3a4ab74ed63c5b8d3",
+                "sha256:cd1591329333daf94467e699e11015d9c944f44c94d2091f4ac493ced0119449",
+                "sha256:cd5b94d4819c0c89280b7c6109c7b788a576084bf0a480ae17c227b0bc41e109",
+                "sha256:d337bf94052856d1b330d5fcad44582a30c532a2463776e1651bd3294ee7e58b",
+                "sha256:dc251477eae03c20fae8db9c1c23ea2ebc47331bcd73927cdcaecd02af98d3c3",
+                "sha256:dc6d69f8829712a4fd799d2ac8d79bdeff651c2301b081fd5d3fe697bd5b4ab9",
+                "sha256:f2a213c1b699d3f5768a7272de720387ae0122f1becf0901ed6eaa1abd1baf6c",
+                "sha256:f3ad7f221d8a69d32d197e5968d798217a4feebe30144986af71ada8c548e9fa",
+                "sha256:f43e93057cf52a227eda401251c72b6fbe4756f35fa6bfebb5d73b86881e59b0",
+                "sha256:f68470edd70c3ac3b6cd5c2a22a8daf18415203ca1b036aaeb9b0fb6f54e8298",
+                "sha256:fa4b1af3e619b5b0b435e333f3967612db06351217c58bfb50cee5f003db2a5a",
+                "sha256:fc6b14e8602f59c6ba893980bea96571dd0ed83d8ebb9c4479d9ed5425d562e9"
             ],
             "markers": "python_version >= '3.7'",
-            "version": "==2.0.30"
+            "version": "==2.0.31"
         },
         "sqlalchemy-utils": {
             "hashes": [
@@ -1372,11 +1381,11 @@
         },
         "urllib3": {
             "hashes": [
-                "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d",
-                "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"
+                "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472",
+                "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"
             ],
             "markers": "python_version >= '3.10'",
-            "version": "==2.2.1"
+            "version": "==2.2.2"
         },
         "werkzeug": {
             "hashes": [
diff --git a/dbrepo-search-service/lib/dbrepo-1.4.4-py3-none-any.whl b/dbrepo-search-service/lib/dbrepo-1.4.4-py3-none-any.whl
index 7e8fd7fca5aa6158bf57952f7f1050a08b331402..c47413901095398979c90dc1f41313ca044f7838 100644
Binary files a/dbrepo-search-service/lib/dbrepo-1.4.4-py3-none-any.whl and b/dbrepo-search-service/lib/dbrepo-1.4.4-py3-none-any.whl differ
diff --git a/dbrepo-search-service/lib/dbrepo-1.4.4.tar.gz b/dbrepo-search-service/lib/dbrepo-1.4.4.tar.gz
index 3e45d4513a31a1fda334ed9ad2c5cbad3803199a..8755a9707129705ca231b838235e0674a1d79da1 100644
Binary files a/dbrepo-search-service/lib/dbrepo-1.4.4.tar.gz and b/dbrepo-search-service/lib/dbrepo-1.4.4.tar.gz differ
diff --git a/lib/python/dbrepo/AmqpClient.py b/lib/python/dbrepo/AmqpClient.py
index 1afcc2a7b582e7fdac634d6d7a14fdd35c4d3797..f570c5d4cc103dda211e1a74839687b9a3f1a6a3 100644
--- a/lib/python/dbrepo/AmqpClient.py
+++ b/lib/python/dbrepo/AmqpClient.py
@@ -7,6 +7,8 @@ import logging
 
 from dbrepo.api.dto import CreateData
 
+logger = logging.getLogger("AmqpClient")
+
 
 class AmqpClient:
     """
@@ -58,5 +60,5 @@ class AmqpClient:
         connection = pika.BlockingConnection(parameters)
         channel = connection.channel()
         channel.basic_publish(exchange=exchange, routing_key=routing_key,
-                              body=json.dumps(dataclasses.asdict(CreateData(data=data))))
+                              body=CreateData(data=data).model_dump_json())
         connection.close()
diff --git a/lib/python/dbrepo/RestClient.py b/lib/python/dbrepo/RestClient.py
index ae956dd07277830235c6d3ca991190766f8fd7de..54165642fb105cda117f10223b6fd6adffe01053 100644
--- a/lib/python/dbrepo/RestClient.py
+++ b/lib/python/dbrepo/RestClient.py
@@ -1,5 +1,5 @@
-import sys
 import os
+import sys
 import logging
 
 import requests
@@ -10,9 +10,11 @@ from pandas import DataFrame
 from dbrepo.UploadClient import UploadClient
 from dbrepo.api.dto import *
 from dbrepo.api.exceptions import ResponseCodeError, UsernameExistsError, EmailExistsError, NotExistsError, \
-    ForbiddenError, MalformedError, NameExistsError, QueryStoreError, MetadataConsistencyError, ExternalSystemError, \
+    ForbiddenError, MalformedError, NameExistsError, QueryStoreError, ExternalSystemError, \
     AuthenticationError, UploadError, FormatNotAvailable, RequestError, ServiceError, ServiceConnectionError
 
+logger = logging.getLogger("RestClient")
+
 
 class RestClient:
     """
@@ -45,7 +47,7 @@ class RestClient:
             self.secure = os.environ.get('REST_API_SECURE') == 'True'
         else:
             self.secure = secure
-        logging.debug(
+        logger.debug(
             f'initialized rest client with endpoint={self.endpoint}, username={username}, verify_ssl={secure}')
 
     def _wrapper(self, method: str, url: str, params: [(str,)] = None, payload=None, headers: dict = None,
@@ -53,27 +55,27 @@ class RestClient:
         if force_auth and (self.username is None and self.password is None):
             raise AuthenticationError(f"Failed to perform request: authentication required")
         url = f'{self.endpoint}{url}'
-        logging.debug(f'method: {method}')
-        logging.debug(f'url: {url}')
+        logger.debug(f'method: {method}')
+        logger.debug(f'url: {url}')
         if params is not None:
-            logging.debug(f'params: {params}')
+            logger.debug(f'params: {params}')
         if stream is not None:
-            logging.debug(f'stream: {stream}')
-        logging.debug(f'secure: {self.secure}')
+            logger.debug(f'stream: {stream}')
+        logger.debug(f'secure: {self.secure}')
         if headers is not None:
-            logging.debug(f'headers: {headers}')
+            logger.debug(f'headers: {headers}')
         else:
             headers = dict()
-            logging.debug(f'no headers set')
+            logger.debug(f'no headers set')
         if payload is not None:
             payload = payload.model_dump()
         auth = None
         if self.username is None and self.password is not None:
             headers["Authorization"] = f"Bearer {self.password}"
-            logging.debug(f'configured for oidc/bearer auth')
+            logger.debug(f'configured for oidc/bearer auth')
         elif self.username is not None and self.password is not None:
             auth = (self.username, self.password)
-            logging.debug(f'configured for basic auth: username={self.username}, password=(hidden)')
+            logger.debug(f'configured for basic auth: username={self.username}, password=(hidden)')
         return requests.request(method=method, url=url, auth=auth, verify=self.secure,
                                 json=payload, headers=headers, params=params, stream=stream)
 
@@ -165,9 +167,9 @@ class RestClient:
         :returns: The username, if set.
         """
         if self.username is not None:
-            logging.info(f"{self.username}")
+            print(f"{self.username}")
             return self.username
-        logging.info(f"No username set!")
+        print(f"No username set!")
         return None
 
     def get_users(self) -> List[UserBrief]:
@@ -1543,7 +1545,8 @@ class RestClient:
         raise ResponseCodeError(f'Failed to delete database access: response code: {response.status_code} is not '
                                 f'201 (CREATED): {response.text}')
 
-    def create_subset(self, database_id: int, query: str, page: int = 0, size: int = 10) -> Result:
+    def create_subset(self, database_id: int, query: str, page: int = 0, size: int = 10,
+                      df: bool = False) -> Result | DataFrame:
         """
         Executes a SQL query in a database where the current user has at least read access with given database id. The
         result set can be paginated with setting page and size (both). Historic data can be queried by setting
@@ -1553,6 +1556,7 @@ class RestClient:
         :param query: The query statement.
         :param page: The result pagination number. Optional. Default: 0.
         :param size: The result pagination size. Optional. Default: 10.
+        :param df: If true, the result is returned as Pandas DataFrame. Optional. Default: False.
 
         :returns: The result set, if successful.
 
@@ -1571,7 +1575,10 @@ class RestClient:
                                  payload=ExecuteQuery(statement=query))
         if response.status_code == 201:
             body = response.json()
-            return Result.model_validate(body)
+            res = Result.model_validate(body)
+            if df:
+                return DataFrame.from_records(res.result)
+            return res
         if response.status_code == 400:
             raise MalformedError(f'Failed to create subset: {response.text}')
         if response.status_code == 403:
diff --git a/lib/python/dbrepo/UploadClient.py b/lib/python/dbrepo/UploadClient.py
index ebcb5aba57bad1eba1c3e7040bc284f702465c83..05fa133d64b2be902deb81423fef9bdc07e8c66d 100644
--- a/lib/python/dbrepo/UploadClient.py
+++ b/lib/python/dbrepo/UploadClient.py
@@ -4,6 +4,8 @@ import re
 import sys
 from tusclient import client
 
+logger = logging.getLogger("UploadClient")
+
 
 class UploadClient:
     """
@@ -33,5 +35,5 @@ class UploadClient:
         uploader.upload()
         m = re.search('\\/([a-f0-9]+)\\+', uploader.url)
         filename = m.group(0)[1:-1]
-        logging.debug(f'uploaded file {file_path} to storage service with key: {filename}')
+        logger.debug(f'uploaded file {file_path} to storage service with key: {filename}')
         return filename
diff --git a/mkdocs.yml b/mkdocs.yml
index 0c9c1d2a878b47e304fbcde67a78fcf89d98d900..f64ac77869749912be823e4e76682e715fa76928 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -48,7 +48,7 @@ nav:
     - Hazardous Materials: examples/hazard.md
     - Power in Industry 4.0: examples/power.md
     - Transportation Monitoring: examples/transportation.md
-    - XPS: examples/xps.md
+    - XPS Data: examples/xps-data.md
   - publications.md
   - contact.md
 extra_css: