diff --git a/core/modules/field/tests/src/Kernel/EntityReference/Views/EntityReferenceRelationshipTest.php b/core/modules/field/tests/src/Kernel/EntityReference/Views/EntityReferenceRelationshipTest.php
index f1be011b88..2437b2134b 100644
--- a/core/modules/field/tests/src/Kernel/EntityReference/Views/EntityReferenceRelationshipTest.php
+++ b/core/modules/field/tests/src/Kernel/EntityReference/Views/EntityReferenceRelationshipTest.php
@@ -2,12 +2,13 @@
 
 namespace Drupal\Tests\field\Kernel\EntityReference\Views;
 
-use Drupal\entity_test\Entity\EntityTestMulChanged;
-use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\entity_test\Entity\EntityTestMul;
+use Drupal\entity_test\Entity\EntityTestMulChanged;
+use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\Tests\field\Traits\EntityReferenceTestTrait;
 use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
+use Drupal\views\Plugin\views\query\Sql;
 use Drupal\views\Tests\ViewTestData;
 use Drupal\views\Views;
 
@@ -140,7 +141,8 @@ public function testNoDataTableRelationship() {
       $this->assertEquals($this->entities[$index]->id(), $row->_entity->id());
 
       // Test the forward relationship.
-      $this->assertEquals(1, $row->entity_test_mul_property_data_entity_test__field_test_data_i);
+      $alias = Sql::sanitizeAlias('entity_test_mul_property_data_entity_test__field_test_data_id');
+      $this->assertEquals(1, $row->{$alias});
 
       // Test that the correct relationship entity is on the row.
       $this->assertEquals(1, $row->_relationship_entities['field_test_data']->id());
diff --git a/core/modules/views/src/Plugin/views/query/Sql.php b/core/modules/views/src/Plugin/views/query/Sql.php
index 0247bf8c67..1464a324cc 100644
--- a/core/modules/views/src/Plugin/views/query/Sql.php
+++ b/core/modules/views/src/Plugin/views/query/Sql.php
@@ -257,6 +257,7 @@ protected function setDistinct($value = TRUE) {
   public function setCountField($table, $field, $alias = NULL) {
     if (empty($alias)) {
       $alias = $table . '_' . $field;
+      $alias = $this->sanitizeAlias($alias);
     }
     $this->count_field = [
       'table' => $table,
@@ -387,6 +388,7 @@ public function addRelationship($alias, JoinPluginBase $join, $base, $link_point
     while (!empty($this->relationships[$alias])) {
       $alias = $alias_base . '_' . $count++;
     }
+    $alias = $this->sanitizeAlias($alias);
 
     // Make sure this join is adjusted for our relationship.
     if ($link_point && isset($this->relationships[$link_point])) {
@@ -507,6 +509,7 @@ public function queueTable($table, $relationship = NULL, JoinPluginBase $join =
       else {
         $alias = $relationship . '_' . $table;
       }
+      $alias = $this->sanitizeAlias($alias);
     }
 
     // Check this again to make sure we don't blow up existing aliases for already
@@ -516,10 +519,12 @@ public function queueTable($table, $relationship = NULL, JoinPluginBase $join =
     }
 
     $alias = $this->markTable($table, $relationship, $alias);
+    $alias = $this->sanitizeAlias($alias);
 
     // If no alias is specified, give it the default.
     if (!isset($alias)) {
       $alias = $this->tables[$relationship][$table]['alias'] . $this->tables[$relationship][$table]['count'];
+      $alias = $this->sanitizeAlias($alias);
     }
 
     // If this is a relationship based table, add a marker with
@@ -549,6 +554,38 @@ public function queueTable($table, $relationship = NULL, JoinPluginBase $join =
     return $alias;
   }
 
+  /**
+   * Produce a safe alias value.
+   *
+   * We limit the length of the original alias (to a default maximum of 60
+   * characters), incorporating a hash of the original value for uniqueness
+   * if that value was too long to use verbatim.
+   *
+   * This prevents subsequent truncation from creating duplicate aliases
+   * in cases where two or more aliases are identical up to the point of
+   * truncation.  This happens particularly easily with relationships,
+   * where alias names may be built from several concatenated identifiers.
+   *
+   * @param $alias
+   *   The alias to sanitize.
+   * @param $maxlength
+   *   The maximum permitted length for the alias.  Defaults to 60 chars.
+   *
+   * @return string
+   *   The sanitized alias.
+   */
+  public static function sanitizeAlias($alias, $maxlength = 60) {
+    if (!is_string($alias)) {
+      return $alias;
+    }
+    if (strlen($alias) > $maxlength) {
+      $checksum = 'c' . crc32($alias);
+      $pos = strlen($checksum) + strlen($alias) - $maxlength;
+      $alias = $checksum . substr($alias, $pos);
+    }
+    return strtolower(substr($alias, 0, $maxlength));
+  }
+
   protected function markTable($table, $relationship, $alias) {
     // Mark that this table has been added.
     if (empty($this->tables[$relationship][$table])) {
@@ -560,6 +597,7 @@ protected function markTable($table, $relationship, $alias) {
           $alias = $relationship . '__';
         }
         $alias .= $table;
+        $alias = $this->sanitizeAlias($alias);
       }
       $this->tables[$relationship][$table] = [
         'count' => 1,
@@ -805,6 +843,10 @@ public function getTableInfo($table) {
       if (!empty($this->tableQueue[$alias])) {
         return $this->tableQueue[$alias];
       }
+      $alias = $this->sanitizeAlias($alias);
+      if (!empty($this->tableQueue[$alias])) {
+        return $this->tableQueue[$alias];
+      }
     }
   }
 
@@ -854,10 +896,7 @@ public function addField($table, $field, $alias = '', $params = []) {
 
     // PostgreSQL truncates aliases to 63 characters:
     // https://www.drupal.org/node/571548.
-
-    // We limit the length of the original alias up to 60 characters
-    // to get a unique alias later if its have duplicates
-    $alias = strtolower(substr($alias, 0, 60));
+    $alias = $this->sanitizeAlias($alias);
 
     // Create a field info array.
     $field_info = [
@@ -872,7 +911,8 @@ public function addField($table, $field, $alias = '', $params = []) {
     $base = $alias;
     $counter = 0;
     while (!empty($this->fields[$alias]) && $this->fields[$alias] != $field_info) {
-      $field_info['alias'] = $alias = $base . '_' . ++$counter;
+      $alias = $this->sanitizeAlias($base . '_' . ++$counter);
+      $field_info['alias'] = $alias;
     }
 
     if (empty($this->fields[$alias])) {
