diff --git a/core/lib/Drupal/Core/Database/Query/Select.php b/core/lib/Drupal/Core/Database/Query/Select.php
index 93ffa081a6fb5ee27930282ba6aa3c33905018fc..c4fd8535f4504d10abb8c9da935d5e779891eec9 100644
--- a/core/lib/Drupal/Core/Database/Query/Select.php
+++ b/core/lib/Drupal/Core/Database/Query/Select.php
@@ -878,7 +878,10 @@ public function __toString() {
 
     // GROUP BY
     if ($this->group) {
-      $query .= "\nGROUP BY " . implode(', ', $this->group);
+      $group_by_fields = array_map(function (string $field): string {
+        return $this->connection->escapeField($field);
+      }, $this->group);
+      $query .= "\nGROUP BY " . implode(', ', $group_by_fields);
     }
 
     // HAVING
diff --git a/core/modules/views/tests/src/Kernel/QueryGroupByTest.php b/core/modules/views/tests/src/Kernel/QueryGroupByTest.php
index 171688321e4ea53d6238bc96f17d8bacccec755a..20a55769fbd540b6bc4d9809fd024d2a30b787d1 100644
--- a/core/modules/views/tests/src/Kernel/QueryGroupByTest.php
+++ b/core/modules/views/tests/src/Kernel/QueryGroupByTest.php
@@ -230,7 +230,7 @@ public function testGroupByBaseField() {
     $view->displayHandlers->get('default')->options['fields']['name']['group_type'] = 'min';
     unset($view->displayHandlers->get('default')->options['fields']['id']['group_type']);
     $this->executeView($view);
-    $this->assertStringContainsString('GROUP BY entity_test.id', (string) $view->build_info['query'], 'GROUP BY field includes the base table name when grouping on the base field.');
+    $this->assertMatchesRegularExpression('/GROUP BY .*[^\w\s]entity_test[^\w\s]\.[^\w\s]id[^\w\s]/', (string) $view->build_info['query'], 'GROUP BY field includes the base table name when grouping on the base field.');
   }
 
   /**
diff --git a/core/tests/Drupal/KernelTests/Core/Database/ReservedWordTest.php b/core/tests/Drupal/KernelTests/Core/Database/ReservedWordTest.php
index 9bc296c8e67c96b32ced46fc373658fdc930856f..c541f466d46d5933b796e7b9b3dc4ba4a1f1f677 100644
--- a/core/tests/Drupal/KernelTests/Core/Database/ReservedWordTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Database/ReservedWordTest.php
@@ -80,4 +80,30 @@ public function testSelectReservedWordAliasAllFields() {
     $this->assertSame('27', $record->age);
   }
 
+  /**
+   * Tests SELECT query with GROUP BY clauses on fields with reserved names.
+   */
+  public function testGroupBy() {
+    $this->connection->insert('select')
+      ->fields([
+        'id' => 2,
+        'update' => 'Update value 1',
+      ])
+      ->execute();
+
+    // Using aliases.
+    $query = $this->connection->select('select', 's');
+    $query->addExpression('COUNT([id])', 'num');
+    $query->addField('s', 'update');
+    $query->groupBy('s.update');
+    $this->assertSame('2', $query->execute()->fetchAssoc()['num']);
+
+    // Not using aliases.
+    $query = $this->connection->select('select');
+    $query->addExpression('COUNT([id])', 'num');
+    $query->addField('select', 'update');
+    $query->groupBy('update');
+    $this->assertSame('2', $query->execute()->fetchAssoc()['num']);
+  }
+
 }
diff --git a/core/tests/Drupal/KernelTests/Core/Database/SelectComplexTest.php b/core/tests/Drupal/KernelTests/Core/Database/SelectComplexTest.php
index 281f3d4d57c96d589cc05c3b3920f24e3df5acf3..e7df5c4386b18c79db56fe913dca3f8f6542bc5c 100644
--- a/core/tests/Drupal/KernelTests/Core/Database/SelectComplexTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Database/SelectComplexTest.php
@@ -82,6 +82,10 @@ public function testGroupBy() {
     $task_field = $query->addField('t', 'task');
     $query->orderBy($count_field);
     $query->groupBy($task_field);
+
+    $this->assertMatchesRegularExpression("/ORDER BY .*[^\w\s]num[^\w\s]/", (string) $query);
+    $this->assertMatchesRegularExpression("/GROUP BY .*[^\w\s]task[^\w\s]/", (string) $query);
+
     $result = $query->execute();
 
     $num_records = 0;