diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java
index ed867715e1f10051089a4687b3d8568ec6e5f3cf..878502f1bc31776f208fe4af1a085d2af8e2705c 100644
--- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java
+++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java
@@ -9,6 +9,7 @@ import at.tuwien.api.database.query.QueryDto;
 import at.tuwien.api.database.query.QueryPersistDto;
 import at.tuwien.api.error.ApiErrorDto;
 import at.tuwien.exception.*;
+import at.tuwien.mapper.MariaDbMapper;
 import at.tuwien.mapper.MetadataMapper;
 import at.tuwien.service.*;
 import at.tuwien.validation.EndpointValidator;
@@ -48,6 +49,7 @@ import java.util.UUID;
 @RequestMapping(path = "/api/database/{databaseId}/subset")
 public class SubsetEndpoint extends RestEndpoint {
 
+    private final MariaDbMapper mariaDbMapper;
     private final SubsetService subsetService;
     private final MetadataMapper metadataMapper;
     private final MetricsService metricsService;
@@ -57,9 +59,10 @@ public class SubsetEndpoint extends RestEndpoint {
     private final EndpointValidator endpointValidator;
 
     @Autowired
-    public SubsetEndpoint(SubsetService subsetService, MetadataMapper metadataMapper, MetricsService metricsService,
-                          StorageService storageService, DatabaseService databaseService,
+    public SubsetEndpoint(MariaDbMapper mariaDbMapper, SubsetService subsetService, MetadataMapper metadataMapper,
+                          MetricsService metricsService, StorageService storageService, DatabaseService databaseService,
                           CredentialService credentialService, EndpointValidator endpointValidator) {
+        this.mariaDbMapper = mariaDbMapper;
         this.subsetService = subsetService;
         this.metadataMapper = metadataMapper;
         this.metricsService = metricsService;
@@ -188,20 +191,16 @@ public class SubsetEndpoint extends RestEndpoint {
                 return ResponseEntity.ok(subset);
             case "text/csv":
                 log.trace("accept header matches csv");
-                try {
-                    final Dataset<Row> dataset = subsetService.getData(database, subset, null, null);
-                    metricsService.countSubsetGetData(databaseId, subsetId);
-                    final ExportResourceDto resource = storageService.transformDataset(dataset);
-                    final HttpHeaders headers = new HttpHeaders();
-                    headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\"");
-                    log.trace("export table resulted in resource {}", resource);
-                    return ResponseEntity.ok()
-                            .headers(headers)
-                            .body(resource.getResource());
-                } catch (SQLException e) {
-                    log.error("Failed to find data: {}", e.getMessage());
-                    throw new DatabaseUnavailableException("Failed to find data: " + e.getMessage(), e);
-                }
+                final String query = mariaDbMapper.rawSelectQuery(subset.getQuery(), timestamp, null, null);
+                final Dataset<Row> dataset = subsetService.getData(database, query, timestamp, null, null, null, null);
+                metricsService.countSubsetGetData(databaseId, subsetId);
+                final ExportResourceDto resource = storageService.transformDataset(dataset);
+                final HttpHeaders headers = new HttpHeaders();
+                headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\"");
+                log.trace("export table resulted in resource {}", resource);
+                return ResponseEntity.ok()
+                        .headers(headers)
+                        .body(resource.getResource());
         }
         throw new FormatNotAvailableException("Must provide either application/json or text/csv value for header 'Accept': provided " + accept + " instead");
     }
@@ -290,7 +289,7 @@ public class SubsetEndpoint extends RestEndpoint {
         endpointValidator.validateOnlyPrivateSchemaAccess(database, principal);
         try {
             final Long subsetId = subsetService.create(database, data.getStatement(), timestamp, userId);
-            return getData(databaseId, subsetId, principal, request, page, size);
+            return getData(databaseId, subsetId, principal, request, timestamp, page, size);
         } catch (SQLException e) {
             log.error("Failed to establish connection to database: {}", e.getMessage());
             throw new DatabaseUnavailableException("Failed to establish connection to database: " + e.getMessage(), e);
@@ -337,11 +336,12 @@ public class SubsetEndpoint extends RestEndpoint {
                                                              @NotNull @PathVariable("subsetId") Long subsetId,
                                                              Principal principal,
                                                              @NotNull HttpServletRequest request,
+                                                             @RequestParam(required = false) Instant timestamp,
                                                              @RequestParam(required = false) Long page,
                                                              @RequestParam(required = false) Long size)
             throws PaginationException, DatabaseNotFoundException, RemoteUnavailableException, NotAllowedException,
             QueryNotFoundException, DatabaseUnavailableException, TableMalformedException, QueryMalformedException,
-            UserNotFoundException, MetadataServiceException, TableNotFoundException, ViewMalformedException, ViewNotFoundException {
+            UserNotFoundException, MetadataServiceException, TableNotFoundException, ViewNotFoundException {
         log.debug("endpoint get subset data, databaseId={}, subsetId={}, principal.name={} page={}, size={}",
                 databaseId, subsetId, principal != null ? principal.getName() : null, page, size);
         endpointValidator.validateDataParams(page, size);
@@ -363,6 +363,10 @@ public class SubsetEndpoint extends RestEndpoint {
             size = 10L;
             log.debug("size not set: default to {}", size);
         }
+        if (timestamp == null) {
+            timestamp = Instant.now();
+            log.debug("timestamp not set: default to {}", timestamp);
+        }
         try {
             final HttpHeaders headers = new HttpHeaders();
             headers.set("X-Id", "" + subsetId);
@@ -375,7 +379,8 @@ public class SubsetEndpoint extends RestEndpoint {
                         .headers(headers)
                         .build();
             }
-            final Dataset<Row> dataset = subsetService.getData(database, subset, page, size);
+            final String query = mariaDbMapper.rawSelectQuery(subset.getQuery(), timestamp, page, size);
+            final Dataset<Row> dataset = subsetService.getData(database, query, timestamp, page, size, null, null);
             metricsService.countSubsetGetData(databaseId, subsetId);
             final String viewName = metadataMapper.queryDtoToViewName(subset);
             final ViewDto view = databaseService.inspectView(database, viewName);
diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java
index 92ba523f367dc170bd0e60e7113334e34cc697de..82ed0a96f7596e025301f11e6ebceed2cd393acc 100644
--- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java
+++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java
@@ -10,6 +10,7 @@ import at.tuwien.api.database.table.internal.TableCreateDto;
 import at.tuwien.api.error.ApiErrorDto;
 import at.tuwien.exception.*;
 import at.tuwien.gateway.MetadataServiceGateway;
+import at.tuwien.mapper.MariaDbMapper;
 import at.tuwien.service.*;
 import at.tuwien.validation.EndpointValidator;
 import io.micrometer.observation.annotation.Observed;
@@ -48,6 +49,8 @@ import java.util.Map;
 public class TableEndpoint extends RestEndpoint {
 
     private final TableService tableService;
+    private final MariaDbMapper mariaDbMapper;
+    private final SubsetService subsetService;
     private final MetricsService metricsService;
     private final StorageService storageService;
     private final DatabaseService databaseService;
@@ -56,10 +59,13 @@ public class TableEndpoint extends RestEndpoint {
     private final MetadataServiceGateway metadataServiceGateway;
 
     @Autowired
-    public TableEndpoint(TableService tableService, MetricsService metricsService, StorageService storageService,
-                         DatabaseService databaseService, CredentialService credentialService,
-                         EndpointValidator endpointValidator, MetadataServiceGateway metadataServiceGateway) {
+    public TableEndpoint(TableService tableService, MariaDbMapper mariaDbMapper, SubsetService subsetService,
+                         MetricsService metricsService, StorageService storageService, DatabaseService databaseService,
+                         CredentialService credentialService, EndpointValidator endpointValidator,
+                         MetadataServiceGateway metadataServiceGateway) {
         this.tableService = tableService;
+        this.mariaDbMapper = mariaDbMapper;
+        this.subsetService = subsetService;
         this.metricsService = metricsService;
         this.storageService = storageService;
         this.databaseService = databaseService;
@@ -287,8 +293,10 @@ public class TableEndpoint extends RestEndpoint {
             }
             headers.set("Access-Control-Expose-Headers", "X-Headers");
             headers.set("X-Headers", String.join(",", table.getColumns().stream().map(ColumnDto::getInternalName).toList()));
-            final Dataset<Row> dataset = tableService.getData(credentialService.getDatabase(table.getTdbid()),
-                    table.getInternalName(), timestamp, page, size, null, null);
+            final String query = mariaDbMapper.defaultRawSelectQuery(table.getDatabase().getInternalName(),
+                    table.getInternalName(), timestamp, page, size);
+            final Dataset<Row> dataset = subsetService.getData(credentialService.getDatabase(table.getTdbid()),
+                    query, timestamp, page, size, null, null);
             metricsService.countTableGetData(databaseId, tableId);
             return ResponseEntity.ok()
                     .headers(headers)
@@ -624,8 +632,10 @@ public class TableEndpoint extends RestEndpoint {
             }
             credentialService.getAccess(databaseId, getId(principal));
         }
-        final Dataset<Row> dataset = tableService.getData(credentialService.getDatabase(table.getTdbid()),
-                table.getInternalName(), timestamp, null, null, null, null);
+        final String query = mariaDbMapper.defaultRawSelectQuery(table.getDatabase().getInternalName(),
+                table.getInternalName(), timestamp, null, null);
+        final Dataset<Row> dataset = subsetService.getData(credentialService.getDatabase(table.getTdbid()),
+                query, timestamp, null, null, null, null);
         metricsService.countTableGetData(databaseId, tableId);
         final ExportResourceDto resource = storageService.transformDataset(dataset);
         final HttpHeaders headers = new HttpHeaders();
diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java
index c662bf49c1a10ada160f41b45020613448d0c396..d4eccd0772eba12e007c6e99ae42a60b1304fca5 100644
--- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java
+++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java
@@ -1,12 +1,13 @@
 package at.tuwien.endpoints;
 
 import at.tuwien.ExportResourceDto;
+import at.tuwien.api.database.CreateViewDto;
 import at.tuwien.api.database.DatabaseDto;
 import at.tuwien.api.database.ViewColumnDto;
-import at.tuwien.api.database.ViewCreateDto;
 import at.tuwien.api.database.ViewDto;
 import at.tuwien.api.error.ApiErrorDto;
 import at.tuwien.exception.*;
+import at.tuwien.mapper.MariaDbMapper;
 import at.tuwien.service.*;
 import at.tuwien.validation.EndpointValidator;
 import io.micrometer.observation.annotation.Observed;
@@ -45,6 +46,8 @@ public class ViewEndpoint extends RestEndpoint {
 
     private final ViewService viewService;
     private final TableService tableService;
+    private final MariaDbMapper mariaDbMapper;
+    private final SubsetService subsetService;
     private final MetricsService metricsService;
     private final StorageService storageService;
     private final DatabaseService databaseService;
@@ -52,11 +55,14 @@ public class ViewEndpoint extends RestEndpoint {
     private final EndpointValidator endpointValidator;
 
     @Autowired
-    public ViewEndpoint(ViewService viewService, TableService tableService, MetricsService metricsService,
-                        StorageService storageService, DatabaseService databaseService,
-                        CredentialService credentialService, EndpointValidator endpointValidator) {
+    public ViewEndpoint(ViewService viewService, TableService tableService, MariaDbMapper mariaDbMapper,
+                        SubsetService subsetService, MetricsService metricsService, StorageService storageService,
+                        DatabaseService databaseService, CredentialService credentialService,
+                        EndpointValidator endpointValidator) {
         this.viewService = viewService;
         this.tableService = tableService;
+        this.mariaDbMapper = mariaDbMapper;
+        this.subsetService = subsetService;
         this.metricsService = metricsService;
         this.storageService = storageService;
         this.databaseService = databaseService;
@@ -147,7 +153,7 @@ public class ViewEndpoint extends RestEndpoint {
                             schema = @Schema(implementation = ApiErrorDto.class))}),
     })
     public ResponseEntity<ViewDto> create(@NotNull @PathVariable("databaseId") Long databaseId,
-                                          @Valid @RequestBody ViewCreateDto data) throws DatabaseUnavailableException,
+                                          @Valid @RequestBody CreateViewDto data) throws DatabaseUnavailableException,
             DatabaseNotFoundException, RemoteUnavailableException, ViewMalformedException, MetadataServiceException {
         log.debug("endpoint create view, databaseId={}, data.name={}", databaseId, data.getName());
         final DatabaseDto database = credentialService.getDatabase(databaseId);
@@ -288,8 +294,10 @@ public class ViewEndpoint extends RestEndpoint {
             }
             headers.set("Access-Control-Expose-Headers", "X-Headers");
             headers.set("X-Headers", String.join(",", view.getColumns().stream().map(ViewColumnDto::getInternalName).toList()));
-            final Dataset<Row> dataset = tableService.getData(credentialService.getDatabase(databaseId),
-                    view.getInternalName(), timestamp, page, size, null, null);
+            final String query = mariaDbMapper.defaultRawSelectQuery(view.getDatabase().getInternalName(),
+                    view.getInternalName(), timestamp, page, size);
+            final Dataset<Row> dataset = subsetService.getData(credentialService.getDatabase(databaseId),
+                    query, timestamp, page, size, null, null);
             metricsService.countViewGetData(databaseId, viewId);
             return ResponseEntity.ok()
                     .headers(headers)
@@ -353,8 +361,10 @@ public class ViewEndpoint extends RestEndpoint {
             }
             credentialService.getAccess(databaseId, getId(principal));
         }
-        final Dataset<Row> dataset = tableService.getData(credentialService.getDatabase(databaseId),
-                view.getInternalName(), timestamp, null, null, null, null);
+        final String query = mariaDbMapper.defaultRawSelectQuery(view.getDatabase().getInternalName(),
+                view.getInternalName(), timestamp, null, null);
+        final Dataset<Row> dataset = subsetService.getData(credentialService.getDatabase(databaseId),
+                query, timestamp, null, null, null, null);
         metricsService.countViewGetData(databaseId, viewId);
         final ExportResourceDto resource = storageService.transformDataset(dataset);
         final HttpHeaders headers = new HttpHeaders();
diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java
index 002374fe9d5f6d3cd2e3b94f0df49b5a3365c6d7..53393be4073d4804b65c4dde13b248612b59d143 100644
--- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java
+++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/SubsetEndpointUnitTest.java
@@ -1,5 +1,6 @@
 package at.tuwien.endpoint;
 
+import at.tuwien.api.SortTypeDto;
 import at.tuwien.api.database.DatabaseDto;
 import at.tuwien.api.database.query.ExecuteStatementDto;
 import at.tuwien.api.database.query.QueryDto;
@@ -206,7 +207,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(QUERY_5_DTO);
         when(storageService.transformDataset(any(Dataset.class)))
                 .thenReturn(EXPORT_RESOURCE_DTO);
-        when(subsetService.getData(any(DatabaseDto.class), any(QueryDto.class), eq(0L), eq(10L)))
+        when(subsetService.getData(any(DatabaseDto.class), anyString(), any(Instant.class), eq(0L), eq(10L), any(SortTypeDto.class), anyString()))
                 .thenReturn(mock);
 
         /* test */
@@ -232,7 +233,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
     @WithAnonymousUser
     public void findById_publicDataPublicSchemaAnonymous_fails() throws DatabaseNotFoundException, SQLException,
             RemoteUnavailableException, UserNotFoundException, QueryMalformedException, StorageUnavailableException,
-            QueryNotFoundException, MetadataServiceException, TableNotFoundException, ViewMalformedException {
+            QueryNotFoundException, MetadataServiceException, TableNotFoundException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
 
         /* mock */
@@ -240,7 +241,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(DATABASE_3_DTO);
         when(subsetService.findById(DATABASE_4_DTO, QUERY_5_ID))
                 .thenReturn(QUERY_5_DTO);
-        when(subsetService.getData(any(DatabaseDto.class), any(QueryDto.class), eq(0L), eq(10L)))
+        when(subsetService.getData(any(DatabaseDto.class), anyString(), any(Instant.class), eq(0L), eq(10L), any(SortTypeDto.class), anyString()))
                 .thenReturn(mock);
         when(storageService.transformDataset(any(Dataset.class)))
                 .thenReturn(EXPORT_RESOURCE_DTO);
@@ -289,8 +290,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
     @WithMockUser(username = USER_1_USERNAME)
     public void findById_publicDataPrivateSchemaUnavailableExport_fails() throws DatabaseNotFoundException,
             RemoteUnavailableException, MetadataServiceException, SQLException, QueryMalformedException,
-            UserNotFoundException, QueryNotFoundException, TableNotFoundException, ViewMalformedException,
-            StorageUnavailableException {
+            UserNotFoundException, QueryNotFoundException, TableNotFoundException, StorageUnavailableException {
 
         /* mock */
         when(credentialService.getDatabase(DATABASE_3_ID))
@@ -301,7 +301,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(EXPORT_RESOURCE_DTO);
         doThrow(SQLException.class)
                 .when(subsetService)
-                .getData(eq(DATABASE_3_DTO), eq(QUERY_5_DTO), eq(0L), eq(10L));
+                .getData(any(DatabaseDto.class), anyString(), any(Instant.class), eq(0L), eq(10L), any(SortTypeDto.class), anyString());
 
         /* test */
         assertThrows(DatabaseUnavailableException.class, () -> {
@@ -324,7 +324,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
         /* mock */
         when(credentialService.getDatabase(DATABASE_3_ID))
                 .thenReturn(DATABASE_3_DTO);
-        when(subsetService.getData(eq(DATABASE_3_DTO), any(QueryDto.class), eq(0L), eq(10L)))
+        when(subsetService.getData(any(DatabaseDto.class), anyString(), any(Instant.class), eq(0L), eq(10L), any(SortTypeDto.class), anyString()))
                 .thenReturn(mock);
         when(subsetService.findById(eq(DATABASE_3_DTO), anyLong()))
                 .thenReturn(QUERY_5_DTO);
@@ -370,7 +370,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(DATABASE_3_DTO);
         when(subsetService.findById(eq(DATABASE_3_DTO), anyLong()))
                 .thenReturn(QUERY_5_DTO);
-        when(subsetService.getData(eq(DATABASE_3_DTO), any(QueryDto.class), eq(0L), eq(10L)))
+        when(subsetService.getData(any(DatabaseDto.class), anyString(), any(Instant.class), eq(0L), eq(10L), any(SortTypeDto.class), anyString()))
                 .thenReturn(mock);
         when(httpServletRequest.getMethod())
                 .thenReturn("POST");
@@ -394,7 +394,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(DATABASE_3_DTO);
         doThrow(SQLException.class)
                 .when(subsetService)
-                .getData(eq(DATABASE_3_DTO), any(QueryDto.class), eq(0L), eq(10L));
+                .getData(any(DatabaseDto.class), anyString(), any(Instant.class), eq(0L), eq(10L), any(SortTypeDto.class), anyString());
         when(subsetService.findById(eq(DATABASE_3_DTO), anyLong()))
                 .thenReturn(QUERY_5_DTO);
         when(metadataServiceGateway.getAccess(DATABASE_3_ID, USER_1_ID))
@@ -447,7 +447,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
         /* mock */
         when(credentialService.getDatabase(DATABASE_3_ID))
                 .thenReturn(DATABASE_3_DTO);
-        when(subsetService.getData(eq(DATABASE_3_DTO), any(QueryDto.class), eq(0L), eq(10L)))
+        when(subsetService.getData(any(DatabaseDto.class), anyString(), any(Instant.class), eq(0L), eq(10L), any(SortTypeDto.class), anyString()))
                 .thenReturn(mock);
         when(subsetService.findById(eq(DATABASE_3_DTO), anyLong()))
                 .thenReturn(QUERY_5_DTO);
@@ -475,7 +475,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(DATABASE_4_DTO);
         when(subsetService.findById(eq(DATABASE_4_DTO), anyLong()))
                 .thenReturn(QUERY_5_DTO);
-        when(subsetService.getData(eq(DATABASE_4_DTO), any(QueryDto.class), eq(0L), eq(10L)))
+        when(subsetService.getData(any(DatabaseDto.class), anyString(), any(Instant.class), eq(0L), eq(10L), any(SortTypeDto.class), anyString()))
                 .thenReturn(mock);
         when(httpServletRequest.getMethod())
                 .thenReturn("POST");
@@ -501,7 +501,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(DATABASE_1_DTO);
         when(subsetService.findById(eq(DATABASE_1_DTO), anyLong()))
                 .thenReturn(QUERY_1_DTO);
-        when(subsetService.getData(eq(DATABASE_1_DTO), any(QueryDto.class), eq(0L), eq(10L)))
+        when(subsetService.getData(any(DatabaseDto.class), anyString(), any(Instant.class), eq(0L), eq(10L), any(SortTypeDto.class), anyString()))
                 .thenReturn(mock);
         when(httpServletRequest.getMethod())
                 .thenReturn("POST");
@@ -514,7 +514,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
     @WithAnonymousUser
     public void create_privateDataPublicSchemaAnonymous_fails() throws DatabaseNotFoundException, SQLException,
             MetadataServiceException, UserNotFoundException, QueryNotFoundException, QueryMalformedException,
-            TableNotFoundException, ViewMalformedException, ViewNotFoundException, RemoteUnavailableException {
+            TableNotFoundException, RemoteUnavailableException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
         final ExecuteStatementDto request = ExecuteStatementDto.builder()
                 .statement(QUERY_5_STATEMENT)
@@ -525,7 +525,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(DATABASE_2_DTO);
         when(subsetService.findById(eq(DATABASE_2_DTO), anyLong()))
                 .thenReturn(QUERY_2_DTO);
-        when(subsetService.getData(eq(DATABASE_2_DTO), any(QueryDto.class), eq(0L), eq(10L)))
+        when(subsetService.getData(any(DatabaseDto.class), anyString(), any(Instant.class), eq(0L), eq(10L), any(SortTypeDto.class), anyString()))
                 .thenReturn(mock);
         when(httpServletRequest.getMethod())
                 .thenReturn("POST");
@@ -540,7 +540,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
     public void getData_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException, UserNotFoundException,
             NotAllowedException, SQLException, QueryNotFoundException, TableMalformedException, QueryMalformedException,
             DatabaseUnavailableException, PaginationException, MetadataServiceException, TableNotFoundException,
-            ViewMalformedException, ViewNotFoundException {
+            ViewNotFoundException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
 
         /* mock */
@@ -550,13 +550,13 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(QUERY_5_DTO);
         when(subsetService.reExecuteCount(DATABASE_3_DTO, QUERY_5_DTO))
                 .thenReturn(QUERY_5_RESULT_NUMBER);
-        when(subsetService.getData(eq(DATABASE_3_DTO), any(QueryDto.class), eq(0L), eq(10L)))
+        when(subsetService.getData(any(DatabaseDto.class), anyString(), any(Instant.class), eq(0L), eq(10L), any(SortTypeDto.class), anyString()))
                 .thenReturn(mock);
         when(httpServletRequest.getMethod())
                 .thenReturn("GET");
 
         /* test */
-        final ResponseEntity<List<Map<String, Object>>> response = subsetEndpoint.getData(DATABASE_3_ID, QUERY_5_ID, null, httpServletRequest, null, null);
+        final ResponseEntity<List<Map<String, Object>>> response = subsetEndpoint.getData(DATABASE_3_ID, QUERY_5_ID, null, httpServletRequest, null, null, null);
         assertEquals(HttpStatus.OK, response.getStatusCode());
         assertNotNull(response.getBody());
     }
@@ -565,7 +565,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
     public void getData_head_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException,
             UserNotFoundException, NotAllowedException, SQLException, QueryNotFoundException, TableMalformedException,
             QueryMalformedException, DatabaseUnavailableException, PaginationException, MetadataServiceException,
-            TableNotFoundException, ViewMalformedException, ViewNotFoundException {
+            TableNotFoundException, ViewNotFoundException {
 
         /* mock */
         when(credentialService.getDatabase(DATABASE_3_ID))
@@ -578,7 +578,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn("HEAD");
 
         /* test */
-        final ResponseEntity<List<Map<String, Object>>> response = subsetEndpoint.getData(DATABASE_3_ID, QUERY_5_ID, null, httpServletRequest, null, null);
+        final ResponseEntity<List<Map<String, Object>>> response = subsetEndpoint.getData(DATABASE_3_ID, QUERY_5_ID, null, httpServletRequest, null, null, null);
         assertEquals(HttpStatus.OK, response.getStatusCode());
         assertNotNull(response.getHeaders().get("X-Count"));
         assertEquals(1, response.getHeaders().get("X-Count").size());
@@ -590,7 +590,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
     public void getData_private_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException,
             UserNotFoundException, DatabaseUnavailableException, NotAllowedException, TableMalformedException,
             QueryMalformedException, QueryNotFoundException, PaginationException, SQLException,
-            MetadataServiceException, TableNotFoundException, ViewMalformedException, ViewNotFoundException {
+            MetadataServiceException, TableNotFoundException, ViewNotFoundException {
         final Dataset<Row> mock = sparkSession.emptyDataFrame();
 
         /* mock */
@@ -600,13 +600,13 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(QUERY_1_DTO);
         when(subsetService.reExecuteCount(DATABASE_1_DTO, QUERY_1_DTO))
                 .thenReturn(QUERY_1_RESULT_NUMBER);
-        when(subsetService.getData(DATABASE_1_DTO, QUERY_1_DTO, 0L, 10L))
+        when(subsetService.getData(DATABASE_1_DTO, QUERY_1_STATEMENT, Instant.now(), 0L, 10L, null, null))
                 .thenReturn(mock);
         when(httpServletRequest.getMethod())
                 .thenReturn("GET");
 
         /* test */
-        final ResponseEntity<List<Map<String, Object>>> response = subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, httpServletRequest, null, null);
+        final ResponseEntity<List<Map<String, Object>>> response = subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, httpServletRequest, null, null, null);
         assertEquals(HttpStatus.OK, response.getStatusCode());
         assertNotNull(response.getBody());
     }
@@ -622,7 +622,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(NotAllowedException.class, () -> {
-            subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, null, httpServletRequest, null, null);
+            subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, null, httpServletRequest, null, null, null);
         });
     }
 
@@ -640,7 +640,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
 
         /* test */
         assertThrows(NotAllowedException.class, () -> {
-            subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, httpServletRequest, null, null);
+            subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, httpServletRequest, null, null, null);
         });
     }
 
@@ -649,7 +649,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
     public void getData_privateHead_succeeds() throws DatabaseNotFoundException, RemoteUnavailableException,
             UserNotFoundException, DatabaseUnavailableException, NotAllowedException, TableMalformedException,
             QueryMalformedException, QueryNotFoundException, PaginationException, SQLException,
-            MetadataServiceException, TableNotFoundException, ViewMalformedException, ViewNotFoundException {
+            MetadataServiceException, TableNotFoundException, ViewNotFoundException {
 
         /* mock */
         when(credentialService.getDatabase(DATABASE_1_ID))
@@ -662,7 +662,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn("HEAD");
 
         /* test */
-        final ResponseEntity<List<Map<String, Object>>> response = subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, httpServletRequest, null, null);
+        final ResponseEntity<List<Map<String, Object>>> response = subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, httpServletRequest, null, null, null);
         assertEquals(HttpStatus.OK, response.getStatusCode());
         assertNotNull(response.getHeaders().get("X-Count"));
         assertEquals(1, response.getHeaders().get("X-Count").size());
@@ -673,7 +673,7 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
     @WithMockUser(username = USER_1_USERNAME)
     public void getData_unavailable_fails() throws DatabaseNotFoundException, RemoteUnavailableException, SQLException,
             UserNotFoundException, QueryNotFoundException, MetadataServiceException, QueryMalformedException,
-            TableNotFoundException, ViewMalformedException {
+            TableNotFoundException {
 
         /* mock */
         when(credentialService.getDatabase(DATABASE_1_ID))
@@ -684,11 +684,11 @@ public class SubsetEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn("GET");
         doThrow(SQLException.class)
                 .when(subsetService)
-                .getData(DATABASE_1_DTO, QUERY_1_DTO, 0L, 10L);
+                .getData(DATABASE_1_DTO, QUERY_1_STATEMENT, Instant.now(), 0L, 10L, null, null);
 
         /* test */
         assertThrows(DatabaseUnavailableException.class, () -> {
-            subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, httpServletRequest, null, null);
+            subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, httpServletRequest, null, null, null);
         });
     }
 
diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java
index c7a74de17fc6ecc15e410aefb1366a0ab0e81549..ecd745e3eeee7a85c2f54b2525a6f620606a077b 100644
--- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java
+++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/TableEndpointUnitTest.java
@@ -8,6 +8,7 @@ import at.tuwien.exception.*;
 import at.tuwien.gateway.MetadataServiceGateway;
 import at.tuwien.service.CredentialService;
 import at.tuwien.service.DatabaseService;
+import at.tuwien.service.SubsetService;
 import at.tuwien.service.TableService;
 import at.tuwien.test.AbstractUnitTest;
 import jakarta.servlet.http.HttpServletRequest;
@@ -59,6 +60,9 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
     @MockBean
     private TableService tableService;
 
+    @MockBean
+    private SubsetService subsetService;
+
     @MockBean
     private DatabaseService databaseService;
 
@@ -283,7 +287,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
         /* mock */
         when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID))
                 .thenReturn(TABLE_8_DTO);
-        when(tableService.getData(eq(DATABASE_3_DTO), eq(TABLE_8_INTERNAL_NAME), any(Instant.class), eq(0L), eq(10L), eq(null), eq(null)))
+        when(subsetService.getData(eq(DATABASE_3_DTO), eq(TABLE_8_INTERNAL_NAME), any(Instant.class), eq(0L), eq(10L), eq(null), eq(null)))
                 .thenReturn(mock);
         when(httpServletRequest.getMethod())
                 .thenReturn("GET");
@@ -306,7 +310,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(TABLE_8_DTO);
         when(tableService.getCount(eq(TABLE_8_DTO), any(Instant.class)))
                 .thenReturn(3L);
-        when(tableService.getData(eq(DATABASE_3_DTO), eq(TABLE_8_INTERNAL_NAME), any(Instant.class), eq(0L), eq(10L), eq(null), eq(null)))
+        when(subsetService.getData(eq(DATABASE_3_DTO), eq(TABLE_8_INTERNAL_NAME), any(Instant.class), eq(0L), eq(10L), eq(null), eq(null)))
                 .thenReturn(mock);
         when(httpServletRequest.getMethod())
                 .thenReturn("HEAD");
@@ -363,7 +367,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
         when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID))
                 .thenReturn(TABLE_8_DTO);
         doThrow(QueryMalformedException.class)
-                .when(tableService)
+                .when(subsetService)
                 .getData(eq(DATABASE_3_DTO), eq(TABLE_8_INTERNAL_NAME), any(Instant.class), eq(0L), eq(10L), eq(null), eq(null));
         when(httpServletRequest.getMethod())
                 .thenReturn("GET");
@@ -405,7 +409,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(TABLE_1_DTO);
         when(credentialService.getAccess(DATABASE_1_ID, USER_2_ID))
                 .thenReturn(access);
-        when(tableService.getData(eq(DATABASE_1_DTO), eq(TABLE_1_INTERNAL_NAME), any(Instant.class), eq(0L), eq(10L), eq(null), eq(null)))
+        when(subsetService.getData(eq(DATABASE_1_DTO), eq(TABLE_1_INTERNAL_NAME), any(Instant.class), eq(0L), eq(10L), eq(null), eq(null)))
                 .thenReturn(mock);
         when(httpServletRequest.getMethod())
                 .thenReturn("GET");
@@ -1146,7 +1150,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
         /* mock */
         when(credentialService.getTable(DATABASE_3_ID, TABLE_8_ID))
                 .thenReturn(TABLE_8_DTO);
-        when(tableService.getData(eq(DATABASE_3_DTO), eq(TABLE_8_INTERNAL_NAME), any(Instant.class), eq(0L), eq(10L), eq(null), eq(null)))
+        when(subsetService.getData(eq(DATABASE_3_DTO), eq(TABLE_8_INTERNAL_NAME), any(Instant.class), eq(0L), eq(10L), eq(null), eq(null)))
                 .thenReturn(mock);
 
         /* test */
@@ -1167,7 +1171,7 @@ public class TableEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(TABLE_1_DTO);
         when(credentialService.getAccess(DATABASE_1_ID, USER_2_ID))
                 .thenReturn(access);
-        when(tableService.getData(eq(DATABASE_1_DTO), eq(TABLE_1_INTERNAL_NAME), any(Instant.class), eq(0L), eq(10L), eq(null), eq(null)))
+        when(subsetService.getData(eq(DATABASE_1_DTO), eq(TABLE_1_INTERNAL_NAME), any(Instant.class), eq(0L), eq(10L), eq(null), eq(null)))
                 .thenReturn(mock);
 
         /* test */
diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java
index 8586f8f92da772235df50a56ee0f423db9238f10..c69c8d338e854d89892db62de126f465430d1fa3 100644
--- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java
+++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/endpoint/ViewEndpointUnitTest.java
@@ -5,7 +5,7 @@ import at.tuwien.endpoints.ViewEndpoint;
 import at.tuwien.exception.*;
 import at.tuwien.service.CredentialService;
 import at.tuwien.service.DatabaseService;
-import at.tuwien.service.TableService;
+import at.tuwien.service.SubsetService;
 import at.tuwien.service.ViewService;
 import at.tuwien.test.AbstractUnitTest;
 import jakarta.servlet.http.HttpServletRequest;
@@ -51,7 +51,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest {
     private HttpServletRequest httpServletRequest;
 
     @MockBean
-    private TableService tableService;
+    private SubsetService subsetService;
 
     @Autowired
     private ViewEndpoint viewEndpoint;
@@ -282,7 +282,7 @@ public class ViewEndpointUnitTest extends AbstractUnitTest {
                 .thenReturn(VIEW_1_DTO);
         when(credentialService.getAccess(DATABASE_1_ID, USER_1_ID))
                 .thenReturn(DATABASE_1_USER_1_READ_ACCESS_DTO);
-        when(tableService.getData(eq(DATABASE_1_DTO), eq(VIEW_1_INTERNAL_NAME), any(Instant.class), eq(0L), eq(10L), eq(null), eq(null)))
+        when(subsetService.getData(eq(DATABASE_1_DTO), eq(VIEW_1_INTERNAL_NAME), any(Instant.class), eq(0L), eq(10L), eq(null), eq(null)))
                 .thenReturn(mock);
         when(httpServletRequest.getMethod())
                 .thenReturn("GET");
diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java
index e48f0c048da2dd6c83934566e6e5d9956838ba62..120fe49d8f98f61e36840b69d8c33fa00bc27053 100644
--- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java
+++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/mvc/PrometheusEndpointMvcTest.java
@@ -140,7 +140,7 @@ public class PrometheusEndpointMvcTest extends AbstractUnitTest {
             /* ignore */
         }
         try {
-            subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, httpServletRequest, 0L, 10L);
+            subsetEndpoint.getData(DATABASE_1_ID, QUERY_1_ID, USER_1_PRINCIPAL, httpServletRequest, null, 0L, 10L);
         } catch (Exception e) {
             /* ignore */
         }
diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java
index 2b7476e50fdaf2fc3b00eaee4552be18959b48f0..550589df794b5839e37b359f4a1b97992d410309 100644
--- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java
+++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/DatabaseServiceIntegrationTest.java
@@ -4,12 +4,12 @@ import at.tuwien.api.database.ViewColumnDto;
 import at.tuwien.api.database.ViewDto;
 import at.tuwien.api.database.table.TableBriefDto;
 import at.tuwien.api.database.table.TableDto;
-import at.tuwien.api.database.table.columns.ColumnCreateDto;
 import at.tuwien.api.database.table.columns.ColumnDto;
 import at.tuwien.api.database.table.columns.ColumnTypeDto;
-import at.tuwien.api.database.table.constraints.ConstraintsCreateDto;
+import at.tuwien.api.database.table.columns.CreateTableColumnDto;
 import at.tuwien.api.database.table.constraints.ConstraintsDto;
-import at.tuwien.api.database.table.constraints.foreign.ForeignKeyCreateDto;
+import at.tuwien.api.database.table.constraints.CreateTableConstraintsDto;
+import at.tuwien.api.database.table.constraints.foreign.CreateForeignKeyDto;
 import at.tuwien.api.database.table.constraints.foreign.ForeignKeyDto;
 import at.tuwien.api.database.table.constraints.foreign.ForeignKeyReferenceDto;
 import at.tuwien.api.database.table.constraints.foreign.ReferenceTypeDto;
@@ -619,8 +619,8 @@ public class DatabaseServiceIntegrationTest extends AbstractUnitTest {
         final at.tuwien.api.database.table.internal.TableCreateDto request = TableCreateDto.builder()
                 .name("missing_foreign_key")
                 .columns(List.of())
-                .constraints(ConstraintsCreateDto.builder()
-                        .foreignKeys(List.of(ForeignKeyCreateDto.builder()
+                .constraints(CreateTableConstraintsDto.builder()
+                        .foreignKeys(List.of(CreateForeignKeyDto.builder()
                                 .columns(List.of("i_do_not_exist"))
                                 .referencedTable("neither_do_i")
                                 .referencedColumns(List.of("behold"))
@@ -639,27 +639,27 @@ public class DatabaseServiceIntegrationTest extends AbstractUnitTest {
             TableExistsException {
         final at.tuwien.api.database.table.internal.TableCreateDto request = TableCreateDto.builder()
                 .name("composite_primary_key")
-                .columns(List.of(ColumnCreateDto.builder()
+                .columns(List.of(CreateTableColumnDto.builder()
                                 .name("name")
                                 .type(ColumnTypeDto.VARCHAR)
                                 .size(255L)
                                 .nullAllowed(false)
                                 .build(),
-                        ColumnCreateDto.builder()
+                        CreateTableColumnDto.builder()
                                 .name("lat")
                                 .type(ColumnTypeDto.DECIMAL)
                                 .size(10L)
                                 .d(10L)
                                 .nullAllowed(false)
                                 .build(),
-                        ColumnCreateDto.builder()
+                        CreateTableColumnDto.builder()
                                 .name("lng")
                                 .type(ColumnTypeDto.DECIMAL)
                                 .size(10L)
                                 .d(10L)
                                 .nullAllowed(false)
                                 .build()))
-                .constraints(ConstraintsCreateDto.builder()
+                .constraints(CreateTableConstraintsDto.builder()
                         .primaryKey(Set.of("lat", "lng"))
                         .foreignKeys(List.of())
                         .checks(Set.of())
diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java
index d3af54816436699c413db11ff59cf213656b46a7..0e89f79cb116682b78bac224981255c0c5196ad2 100644
--- a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java
+++ b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java
@@ -4,9 +4,9 @@ import at.tuwien.api.database.table.TableDto;
 import at.tuwien.api.database.table.TupleDeleteDto;
 import at.tuwien.api.database.table.TupleDto;
 import at.tuwien.api.database.table.TupleUpdateDto;
-import at.tuwien.api.database.table.columns.ColumnCreateDto;
 import at.tuwien.api.database.table.columns.ColumnDto;
 import at.tuwien.api.database.table.columns.ColumnTypeDto;
+import at.tuwien.api.database.table.columns.CreateTableColumnDto;
 import at.tuwien.exception.QueryMalformedException;
 import at.tuwien.exception.TableMalformedException;
 import at.tuwien.utils.MariaDbUtil;
@@ -237,7 +237,7 @@ public interface MariaDbMapper {
      * @param data The column definition.
      * @return The MySQL string.
      */
-    default String columnTypeDtoToDataType(ColumnCreateDto data) {
+    default String columnTypeDtoToDataType(CreateTableColumnDto data) {
         return switch (data.getType()) {
             case CHAR -> "CHAR(" + Objects.requireNonNullElse(data.getSize(), "1") + ")";
             case VARCHAR -> "VARCHAR(" + Objects.requireNonNullElse(data.getSize(), "255") + ")";
@@ -260,7 +260,7 @@ public interface MariaDbMapper {
         };
     }
 
-    default String columnCreateDtoToPrimaryKeyLengthSpecification(ColumnCreateDto data) {
+    default String columnCreateDtoToPrimaryKeyLengthSpecification(CreateTableColumnDto data) {
         if (EnumSet.of(ColumnTypeDto.BLOB, ColumnTypeDto.TEXT).contains(data.getType())) {
             return "(" + Objects.requireNonNullElse(data.getIndexLength(), 255) + ")";
         }
@@ -309,7 +309,7 @@ public interface MariaDbMapper {
                 .append("` (");
         log.trace("primary key column(s) exist: {}", data.getConstraints().getPrimaryKey());
         final int[] idx = {0};
-        for (ColumnCreateDto column : data.getColumns()) {
+        for (CreateTableColumnDto column : data.getColumns()) {
             stringBuilder.append(idx[0]++ > 0 ? ", " : "")
                     .append("`")
                     .append(nameToInternalName(column.getName()))
@@ -336,11 +336,11 @@ public interface MariaDbMapper {
                                 .getPrimaryKey()
                                 .stream()
                                 .map(c -> {
-                                    final Optional<ColumnCreateDto> optional = data.getColumns()
+                                    final Optional<CreateTableColumnDto> optional = data.getColumns()
                                             .stream()
                                             .filter(cc -> cc.getName().equals(c))
                                             .findFirst();
-                                    log.trace("lookup {} in columns: {}", c, data.getColumns().stream().map(ColumnCreateDto::getName).toList());
+                                    log.trace("lookup {} in columns: {}", c, data.getColumns().stream().map(CreateTableColumnDto::getName).toList());
                                     return "`" + nameToInternalName(c) + "`" + columnCreateDtoToPrimaryKeyLengthSpecification(optional.get());
                                 })
                                 .toArray(String[]::new)))
@@ -725,6 +725,30 @@ public interface MariaDbMapper {
         }
     }
 
+    default String rawSelectQuery(String query, Instant timestamp, Long page, Long size) {
+        /* query check (this is enforced by the db also) */
+        final StringBuilder statement = new StringBuilder("SELECT * FROM (")
+                .append(query);
+        statement.append(")");
+        if (timestamp != null) {
+            statement.append(" FOR SYSTEM_TIME AS OF TIMESTAMP '")
+                    .append(mariaDbFormatter.format(timestamp))
+                    .append("'");
+        }
+        statement.append(" as tbl");
+        /* pagination */
+        if (size != null && page != null) {
+            log.trace("pagination size/limit of {}", size);
+            statement.append(" LIMIT ")
+                    .append(size);
+            log.trace("pagination page/offset of {}", page);
+            statement.append(" OFFSET ")
+                    .append(page * size);
+        }
+        log.trace("mapped select query: {}", statement);
+        return statement.toString();
+    }
+
     default String defaultRawSelectQuery(String databaseName, String tableOrViewName, Instant timestamp, Long page,
                                          Long size) {
         /* query check (this is enforced by the db also) */
diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/DatabaseService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/DatabaseService.java
index 5a120f44d288f5a1fadb5d0c75d478a097558725..314148663b1230cab6a2d3afc903cd301abbd2e0 100644
--- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/DatabaseService.java
+++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/DatabaseService.java
@@ -1,7 +1,7 @@
 package at.tuwien.service;
 
+import at.tuwien.api.database.CreateViewDto;
 import at.tuwien.api.database.DatabaseDto;
-import at.tuwien.api.database.ViewCreateDto;
 import at.tuwien.api.database.ViewDto;
 import at.tuwien.api.database.table.TableDto;
 import at.tuwien.api.database.table.internal.TableCreateDto;
@@ -48,7 +48,7 @@ public interface DatabaseService {
      * @throws SQLException
      * @throws ViewMalformedException
      */
-    ViewDto createView(DatabaseDto database, ViewCreateDto data) throws SQLException,
+    ViewDto createView(DatabaseDto database, CreateViewDto data) throws SQLException,
             ViewMalformedException;
 
     /**
diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/SubsetService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/SubsetService.java
index b2de5cecca0d5ec607563e658ee210186997a91e..e2fc56002799d26e75fc05ca496cb76d330cdb07 100644
--- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/SubsetService.java
+++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/SubsetService.java
@@ -1,5 +1,6 @@
 package at.tuwien.service;
 
+import at.tuwien.api.SortTypeDto;
 import at.tuwien.api.database.DatabaseDto;
 import at.tuwien.api.database.query.QueryDto;
 import at.tuwien.exception.*;
@@ -13,22 +14,6 @@ import java.util.UUID;
 
 public interface SubsetService {
 
-    /**
-     * Retrieve data from a subset in a database and optionally paginate with number of page and size of results.
-     *
-     * @param database The database.
-     * @param subset   The subset.
-     * @param page     The page number.
-     * @param size     Te result size.
-     * @return The data.
-     * @throws ViewMalformedException  The view is malformed.
-     * @throws SQLException            The connection to the database could not be established.
-     * @throws QueryMalformedException The mapped query produced a database error.
-     * @throws TableNotFoundException  The database table is malformed.
-     */
-    Dataset<Row> getData(DatabaseDto database, QueryDto subset, Long page, Long size)
-            throws ViewMalformedException, SQLException, QueryMalformedException, TableNotFoundException;
-
     /**
      * Creates a subset from the given statement at given time in the given database.
      *
@@ -55,6 +40,21 @@ public interface SubsetService {
     Long reExecuteCount(DatabaseDto database, QueryDto query) throws TableMalformedException,
             SQLException, QueryMalformedException;
 
+    /**
+     * Retrieve data from a subset in a database and optionally paginate with number of page and size of results.
+     *
+     * @param database The database.
+     * @param query   The query statements.
+     * @param page     The page number.
+     * @param size     Te result size.
+     * @return The data.
+     * @throws QueryMalformedException The mapped query produced a database error.
+     * @throws TableNotFoundException  The database table is malformed.
+     */
+    Dataset<Row> getData(DatabaseDto database, String query, Instant timestamp, Long page, Long size,
+                         SortTypeDto sortDirection, String sortColumn) throws QueryMalformedException,
+            TableNotFoundException;
+
     /**
      * Finds all queries in the query store of the given database id and query id.
      *
diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/TableService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/TableService.java
index 636e12ceb687cb3c6ce9d3988931caea676ef7ad..f664a82cf32050512f5eeb7d9e2b206289153568 100644
--- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/TableService.java
+++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/TableService.java
@@ -1,12 +1,8 @@
 package at.tuwien.service;
 
-import at.tuwien.api.SortTypeDto;
-import at.tuwien.api.database.DatabaseDto;
 import at.tuwien.api.database.query.ImportDto;
 import at.tuwien.api.database.table.*;
 import at.tuwien.exception.*;
-import org.apache.spark.sql.Dataset;
-import org.apache.spark.sql.Row;
 
 import java.sql.SQLException;
 import java.time.Instant;
@@ -122,8 +118,4 @@ public interface TableService {
      */
     void updateTuple(TableDto table, TupleUpdateDto data) throws SQLException,
             QueryMalformedException, TableMalformedException;
-
-    Dataset<Row> getData(DatabaseDto database, String tableOrView, Instant timestamp,
-                         Long page, Long size, SortTypeDto sortDirection, String sortColumn)
-            throws QueryMalformedException, TableNotFoundException;
 }
diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/DataConnector.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/DataConnector.java
index c21d37721b051bf4109b6062a1ffad493c503850..1786ca5cb44ccef1c52d56af1411b4caf436fa1e 100644
--- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/DataConnector.java
+++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/DataConnector.java
@@ -49,15 +49,11 @@ public abstract class DataConnector {
     }
 
     public String getSparkUrl(TableDto table) {
-        return getSparkUrl(table.getDatabase().getContainer(), null);
+        return getSparkUrl(table.getDatabase().getContainer(), table.getDatabase().getInternalName());
     }
 
     public String getSparkUrl(DatabaseDto databaseDto) {
-        return getSparkUrl(databaseDto.getContainer(), null);
-    }
-
-    public String getSparkUrl(ContainerDto container) {
-        return getSparkUrl(container, null);
+        return getSparkUrl(databaseDto.getContainer(), databaseDto.getInternalName());
     }
 
     public String getJdbcUrl(ContainerDto container, String databaseName) {
diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceMariaDbImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceMariaDbImpl.java
index c4afe44287abbb5c184fa6ec0f8873d17cf9edcb..d733800a3662adc0d57d2d81624914a8753c1b98 100644
--- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceMariaDbImpl.java
+++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/DatabaseServiceMariaDbImpl.java
@@ -1,7 +1,7 @@
 package at.tuwien.service.impl;
 
+import at.tuwien.api.database.CreateViewDto;
 import at.tuwien.api.database.DatabaseDto;
-import at.tuwien.api.database.ViewCreateDto;
 import at.tuwien.api.database.ViewDto;
 import at.tuwien.api.database.table.TableDto;
 import at.tuwien.api.database.table.constraints.unique.UniqueDto;
@@ -146,7 +146,7 @@ public class DatabaseServiceMariaDbImpl extends DataConnector implements Databas
     }
 
     @Override
-    public ViewDto createView(DatabaseDto database, ViewCreateDto data) throws SQLException,
+    public ViewDto createView(DatabaseDto database, CreateViewDto data) throws SQLException,
             ViewMalformedException {
         final ComboPooledDataSource dataSource = getDataSource(database);
         final Connection connection = dataSource.getConnection();
diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java
index 0a208b2890e8702228fb07ca31654625a17b0dd2..bdfdb14838a608ce87b40a94faebe52a27546a63 100644
--- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java
+++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java
@@ -1,7 +1,7 @@
 package at.tuwien.service.impl;
 
+import at.tuwien.api.SortTypeDto;
 import at.tuwien.api.database.DatabaseDto;
-import at.tuwien.api.database.ViewCreateDto;
 import at.tuwien.api.database.query.QueryDto;
 import at.tuwien.api.identifier.IdentifierBriefDto;
 import at.tuwien.api.identifier.IdentifierTypeDto;
@@ -9,14 +9,13 @@ import at.tuwien.exception.*;
 import at.tuwien.gateway.MetadataServiceGateway;
 import at.tuwien.mapper.DataMapper;
 import at.tuwien.mapper.MariaDbMapper;
-import at.tuwien.mapper.MetadataMapper;
-import at.tuwien.service.DatabaseService;
 import at.tuwien.service.SubsetService;
-import at.tuwien.service.TableService;
 import com.mchange.v2.c3p0.ComboPooledDataSource;
 import lombok.extern.log4j.Log4j2;
 import org.apache.spark.sql.Dataset;
 import org.apache.spark.sql.Row;
+import org.apache.spark.sql.SparkSession;
+import org.apache.spark.sql.catalyst.ExtendedAnalysisException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -31,40 +30,41 @@ import java.util.UUID;
 public class SubsetServiceMariaDbImpl extends DataConnector implements SubsetService {
 
     private final DataMapper dataMapper;
-    private final TableService tableService;
+    private final SparkSession sparkSession;
     private final MariaDbMapper mariaDbMapper;
-    private final MetadataMapper metadataMapper;
-    private final DatabaseService databaseService;
     private final MetadataServiceGateway metadataServiceGateway;
 
     @Autowired
-    public SubsetServiceMariaDbImpl(DataMapper dataMapper, TableService tableService, MariaDbMapper mariaDbMapper,
-                                    MetadataMapper metadataMapper, DatabaseService databaseService,
+    public SubsetServiceMariaDbImpl(DataMapper dataMapper, MariaDbMapper mariaDbMapper, SparkSession sparkSession,
                                     MetadataServiceGateway metadataServiceGateway) {
         this.dataMapper = dataMapper;
-        this.tableService = tableService;
+        this.sparkSession = sparkSession;
         this.mariaDbMapper = mariaDbMapper;
-        this.metadataMapper = metadataMapper;
-        this.databaseService = databaseService;
         this.metadataServiceGateway = metadataServiceGateway;
     }
 
     @Override
-    public Dataset<Row> getData(DatabaseDto database, QueryDto subset, Long page, Long size)
-            throws ViewMalformedException, SQLException, QueryMalformedException, TableNotFoundException {
-        final String viewName = metadataMapper.queryDtoToViewName(subset);
-        if (!databaseService.existsView(database, viewName)) {
-            log.warn("Missing internal view {} for subset with id {}: create it from subset query", viewName, subset.getId());
-            databaseService.createView(database, ViewCreateDto.builder()
-                    .isPublic(false)
-                    .isSchemaPublic(false)
-                    .name(viewName)
-                    .query(subset.getQuery())
-                    .build());
-        } else {
-            log.debug("internal view {}.{} for subset with id {} exists", database.getInternalName(), viewName, subset.getId());
+    public Dataset<Row> getData(DatabaseDto database, String query, Instant timestamp, Long page, Long size,
+                                SortTypeDto sortDirection, String sortColumn)
+            throws QueryMalformedException, TableNotFoundException {
+        try {
+            return sparkSession.read()
+                    .format("jdbc")
+                    .option("user", database.getContainer().getUsername())
+                    .option("password", database.getContainer().getPassword())
+                    .option("url", getSparkUrl(database))
+                    .option("query", query)
+                    .load();
+        } catch (Exception e) {
+            if (e instanceof ExtendedAnalysisException exception) {
+                if (exception.getSimpleMessage().contains("TABLE_OR_VIEW_NOT_FOUND")) {
+                    log.error("Failed to find named reference: {}", exception.getSimpleMessage());
+                    throw new TableNotFoundException("Failed to find named reference: " + exception.getSimpleMessage()) /* remove throwable on purpose, clutters the output */;
+                }
+            }
+            log.error("Malformed query: {}", e.getMessage());
+            throw new QueryMalformedException("Malformed query: " + e.getMessage(), e);
         }
-        return tableService.getData(database, viewName, subset.getExecution(), page, size, null, null);
     }
 
     @Override
diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java
index 4d4121f06049251cadebe498ebb32ef9f6a4d409..466f7539fd250666962d08a75ffffd5aa61480fa 100644
--- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java
+++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java
@@ -1,7 +1,5 @@
 package at.tuwien.service.impl;
 
-import at.tuwien.api.SortTypeDto;
-import at.tuwien.api.database.DatabaseDto;
 import at.tuwien.api.database.query.ImportDto;
 import at.tuwien.api.database.table.*;
 import at.tuwien.api.database.table.columns.ColumnDto;
@@ -16,8 +14,10 @@ import at.tuwien.service.TableService;
 import at.tuwien.utils.MariaDbUtil;
 import com.mchange.v2.c3p0.ComboPooledDataSource;
 import lombok.extern.log4j.Log4j2;
-import org.apache.spark.sql.*;
-import org.apache.spark.sql.catalyst.ExtendedAnalysisException;
+import org.apache.spark.sql.AnalysisException;
+import org.apache.spark.sql.Dataset;
+import org.apache.spark.sql.Row;
+import org.apache.spark.sql.SaveMode;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -36,16 +36,14 @@ import java.util.Properties;
 public class TableServiceMariaDbImpl extends DataConnector implements TableService {
 
     private final DataMapper dataMapper;
-    private final SparkSession sparkSession;
     private final MariaDbMapper mariaDbMapper;
     private final StorageService storageService;
     private final DatabaseService databaseService;
 
     @Autowired
-    public TableServiceMariaDbImpl(DataMapper dataMapper, SparkSession sparkSession, MariaDbMapper mariaDbMapper,
-                                   StorageService storageService, DatabaseService databaseService) {
+    public TableServiceMariaDbImpl(DataMapper dataMapper, MariaDbMapper mariaDbMapper, StorageService storageService,
+                                   DatabaseService databaseService) {
         this.dataMapper = dataMapper;
-        this.sparkSession = sparkSession;
         this.mariaDbMapper = mariaDbMapper;
         this.storageService = storageService;
         this.databaseService = databaseService;
@@ -368,30 +366,4 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi
                 .getColumnType();
     }
 
-    @Override
-    public Dataset<Row> getData(DatabaseDto database, String tableOrView, Instant timestamp,
-                                Long page, Long size, SortTypeDto sortDirection, String sortColumn)
-            throws QueryMalformedException, TableNotFoundException {
-        try {
-            return sparkSession.read()
-                    .format("jdbc")
-                    .option("user", database.getContainer().getUsername())
-                    .option("password", database.getContainer().getPassword())
-                    .option("url", getSparkUrl(database))
-                    .option("query", mariaDbMapper.defaultRawSelectQuery(database.getInternalName(), tableOrView,
-                            timestamp, page, size))
-                    .load();
-
-        } catch (Exception e) {
-            if (e instanceof ExtendedAnalysisException exception) {
-                if (exception.getSimpleMessage().contains("TABLE_OR_VIEW_NOT_FOUND")) {
-                    log.error("Failed to find named reference: {}", exception.getSimpleMessage());
-                    throw new TableNotFoundException("Failed to find named reference: " + exception.getSimpleMessage()) /* remove throwable on purpose, clutters the output */;
-                }
-            }
-            log.error("Malformed query: {}", e.getMessage());
-            throw new QueryMalformedException("Malformed query: " + e.getMessage(), e);
-        }
-    }
-
 }