diff --git a/core/modules/views/src/Plugin/views/query/Sql.php b/core/modules/views/src/Plugin/views/query/Sql.php
index 40de924609a..c5e22e497d9 100644
--- a/core/modules/views/src/Plugin/views/query/Sql.php
+++ b/core/modules/views/src/Plugin/views/query/Sql.php
@@ -251,6 +251,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,
@@ -379,6 +380,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])) {
@@ -499,6 +501,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
@@ -508,10 +511,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
@@ -541,6 +546,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 $maxlen
+   *   The maximum permitted length for the alias.  Defaults to 60 chars.
+   *
+   * @return string
+   *   The sanitized alias.
+   */
+  protected function sanitizeAlias($alias, $maxlen = 60) {
+    if (!is_string($alias)) {
+      return $alias;
+    }
+    if (strlen($alias) > $maxlen) {
+      $cksum = 'c' . crc32($alias);
+      $pos = strlen($cksum) + strlen($alias) - $maxlen;
+      $alias = $cksum . substr($alias, $pos);
+    }
+    return strtolower(substr($alias, 0, $maxlen));
+  }
+
   protected function markTable($table, $relationship, $alias) {
     // Mark that this table has been added.
     if (empty($this->tables[$relationship][$table])) {
@@ -552,6 +589,7 @@ protected function markTable($table, $relationship, $alias) {
           $alias = $relationship . '__';
         }
         $alias .= $table;
+        $alias = $this->sanitizeAlias($alias);
       }
       $this->tables[$relationship][$table] = [
         'count' => 1,
@@ -793,6 +831,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];
+      }
     }
   }
 
@@ -841,10 +883,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 = [
@@ -859,7 +898,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])) {
