diff --git a/src/bp-xprofile/bp-xprofile-filters.php b/src/bp-xprofile/bp-xprofile-filters.php
index dd3f7c567..33997a130 100644
--- a/src/bp-xprofile/bp-xprofile-filters.php
+++ b/src/bp-xprofile/bp-xprofile-filters.php
@@ -154,11 +154,13 @@ function xprofile_filter_kses( $content, $data_obj = null ) {
  * Safely runs profile field data through kses and force_balance_tags.
  *
  * @since 1.2.6
+ * @since 3.0.0 The `$field_value` parameter accepts an array.
  *
- * @param string      $field_value Field value being santized.
- * @param int         $field_id    Field ID being sanitized.
- * @param bool        $reserialize Whether to reserialize arrays before returning. Defaults to true.
- * @param object|null $data_obj    The BP_XProfile_ProfileData object.
+ * @param string       $field_value Field value being santized.
+ * @param int          $field_id    Field ID being sanitized.
+ * @param bool         $reserialize Whether to reserialize arrays before returning. Defaults to true.
+ * @param object|null  $data_obj    The BP_XProfile_ProfileData object.
+ * @return string|array
  * @return string
  */
 function xprofile_sanitize_data_value_before_save( $field_value, $field_id = 0, $reserialize = true, $data_obj = null ) {
@@ -176,8 +178,13 @@ function xprofile_sanitize_data_value_before_save( $field_value, $field_id = 0,
 	// Value might be a serialized array of options.
 	$field_value = maybe_unserialize( $field_value );
 
+	// Return if empty. Special-case support for integer 0 for the number field type.
+	if ( empty( $field_value ) && ! is_integer( $field_value ) && $field_value !== '0' ) {
+		return $field_value;
+	}
+
 	// Sanitize single field value.
-	if ( ! is_array( $field_value ) ) {
+	if ( ! $data_obj || ! bp_xprofile_field_supports_multiple_values( $data_obj->field_id ) ) {
 		$kses_field_value     = xprofile_filter_kses( $field_value, $data_obj );
 		$filtered_field_value = wp_rel_nofollow( force_balance_tags( $kses_field_value ) );
 
@@ -185,26 +192,32 @@ function xprofile_sanitize_data_value_before_save( $field_value, $field_id = 0,
 		 * Filters the kses-filtered data before saving to database.
 		 *
 		 * @since 1.5.0
+		 * @since 3.0.0 The `$filtered_field_value` accepts an array.
 		 *
-		 * @param string                  $filtered_field_value The filtered value.
+		 * @param string|array            $filtered_field_value The filtered value.
 		 * @param string                  $field_value          The original value before filtering.
 		 * @param BP_XProfile_ProfileData $data_obj             The BP_XProfile_ProfileData object.
 		 */
 		$filtered_field_value = apply_filters( 'xprofile_filtered_data_value_before_save', $filtered_field_value, $field_value, $data_obj );
 
+		if ( ! empty( $reserialize ) ) {
+			$filtered_field_value = maybe_serialize( $filtered_field_value );
+		}
+
 	// Sanitize multiple individual option values.
 	} else {
 		$filtered_values = array();
 		foreach ( (array) $field_value as $value ) {
-			$kses_field_value = xprofile_filter_kses( $value, $data_obj );
-			$filtered_value   = wp_rel_nofollow( force_balance_tags( $kses_field_value ) );
+			$unserialized_value = maybe_unserialize( $value );
+			$kses_field_value   = xprofile_filter_kses( $unserialized_value, $data_obj );
+			$filtered_value     = wp_rel_nofollow( force_balance_tags( $kses_field_value ) );
 
 			/** This filter is documented in bp-xprofile/bp-xprofile-filters.php */
 			$filtered_values[] = apply_filters( 'xprofile_filtered_data_value_before_save', $filtered_value, $value, $data_obj );
 		}
 
-		if ( !empty( $reserialize ) ) {
-			$filtered_field_value = serialize( $filtered_values );
+		if ( ! empty( $reserialize ) ) {
+			$filtered_field_value = array_map( 'maybe_serialize', $filtered_values );
 		} else {
 			$filtered_field_value = $filtered_values;
 		}
diff --git a/src/bp-xprofile/bp-xprofile-functions.php b/src/bp-xprofile/bp-xprofile-functions.php
index 337d2cd79..c34625f01 100644
--- a/src/bp-xprofile/bp-xprofile-functions.php
+++ b/src/bp-xprofile/bp-xprofile-functions.php
@@ -362,7 +362,9 @@ function xprofile_get_field_data( $field, $user_id = 0, $multi_format = 'array'
 
 	$values = maybe_unserialize( BP_XProfile_ProfileData::get_value_byid( $field_id, $user_id ) );
 
-	if ( is_array( $values ) ) {
+	// Consider multiple values.
+	if ( bp_xprofile_field_supports_multiple_values( $field_id ) ) {
+		$values = array_map( 'maybe_unserialize', $values );
 		$data = array();
 		foreach( (array) $values as $value ) {
 
@@ -467,7 +469,11 @@ function xprofile_set_field_data( $field, $user_id, $value, $is_required = false
 	$field->user_id  = $user_id;
 
 	// Gets un/reserialized via xprofile_sanitize_data_value_before_save()
-	$field->value    = maybe_serialize( $value );
+	if ( bp_xprofile_field_supports_multiple_values( $field_id ) ) {
+		$field->value = array_map( 'maybe_serialize', $value );
+	} else {
+		$field->value = maybe_serialize( $value );
+	}
 
 	return $field->save();
 }
@@ -641,9 +647,10 @@ function xprofile_get_random_profile_data( $user_id, $exclude_fullname = true )
  * Formats a profile field according to its type. [ TODO: Should really be moved to filters ]
  *
  * @since 1.0.0
+ * @since 3.0.0 The `$field_value` parameter can be an array.
  *
- * @param string $field_type  The type of field: datebox, selectbox, textbox etc.
- * @param string $field_value The actual value.
+ * @param string       $field_type  The type of field: datebox, selectbox, textbox etc.
+ * @param string|array $field_value The actual value.
  * @return string|bool The formatted value, or false if value is empty.
  */
 function xprofile_format_profile_field( $field_type, $field_value ) {
@@ -1146,6 +1153,37 @@ function bp_xprofile_is_richtext_enabled_for_field( $field_id = null ) {
 	return apply_filters( 'bp_xprofile_is_richtext_enabled_for_field', $enabled, $field_id );
 }
 
+/**
+ * Does this profile field support multiple values?
+ *
+ * @since 3.0.0
+ *
+ * @param int|null $field_id Optional. Default current field ID.
+ * @return bool              Whether the field supports multiple values
+ */
+function bp_xprofile_field_supports_multiple_values( $field_id = null ) {
+	if ( ! $field_id ) {
+		$field_id = bp_get_the_profile_field_id();
+	}
+
+	$field = xprofile_get_field( $field_id, null, false );
+
+	$supports = false;
+	if ( $field instanceof BP_XProfile_Field ) {
+		$supports = (bool) $field->type_obj->supports_multiple_values;
+	}
+
+	/**
+	 * Filters whether the given field supports multiple values.
+	 *
+	 * @since 3.0.0
+	 *
+	 * @param bool $supports True if the field supports multiple values, otherwise false.
+	 * @param int  $field_id ID of the field.
+	 */
+	return (bool) apply_filters( 'bp_xprofile_field_supports_multiple_values', $supports, $field_id );
+}
+
 /**
  * Get visibility levels out of the $bp global.
  *
diff --git a/src/bp-xprofile/bp-xprofile-template.php b/src/bp-xprofile/bp-xprofile-template.php
index afe5162ec..e4f8ad277 100644
--- a/src/bp-xprofile/bp-xprofile-template.php
+++ b/src/bp-xprofile/bp-xprofile-template.php
@@ -903,13 +903,14 @@ function bp_the_profile_field_visibility_level_label() {
  * comma-separated string.
  *
  * @since 1.0.0
+ * @since 3.0.0 The `$value` parameter can be an array.
  *
- * @param string $value Content to maybe unserialize.
+ * @param string|array $value Content to maybe unserialize.
  * @return string
  */
 function bp_unserialize_profile_field( $value ) {
-	if ( is_serialized($value) ) {
-		$field_value = @unserialize($value);
+	if ( is_serialized( $value ) || is_array( $value ) ) {
+		$field_value = maybe_unserialize( $value );
 		$field_value = implode( ', ', $field_value );
 		return $field_value;
 	}
diff --git a/src/bp-xprofile/classes/class-bp-xprofile-field-type-checkbox.php b/src/bp-xprofile/classes/class-bp-xprofile-field-type-checkbox.php
index f3717d3dc..895e07082 100644
--- a/src/bp-xprofile/classes/class-bp-xprofile-field-type-checkbox.php
+++ b/src/bp-xprofile/classes/class-bp-xprofile-field-type-checkbox.php
@@ -28,6 +28,7 @@ class BP_XProfile_Field_Type_Checkbox extends BP_XProfile_Field_Type {
 		$this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' );
 		$this->name     = _x( 'Checkboxes', 'xprofile field type', 'buddypress' );
 
+		$this->supports_multiple_values   = true;
 		$this->supports_multiple_defaults = true;
 		$this->accepts_null_value         = true;
 		$this->supports_options           = true;
diff --git a/src/bp-xprofile/classes/class-bp-xprofile-field-type-multiselectbox.php b/src/bp-xprofile/classes/class-bp-xprofile-field-type-multiselectbox.php
index d56b25be4..718b79d2a 100644
--- a/src/bp-xprofile/classes/class-bp-xprofile-field-type-multiselectbox.php
+++ b/src/bp-xprofile/classes/class-bp-xprofile-field-type-multiselectbox.php
@@ -28,6 +28,7 @@ class BP_XProfile_Field_Type_Multiselectbox extends BP_XProfile_Field_Type {
 		$this->category = _x( 'Multi Fields', 'xprofile field type category', 'buddypress' );
 		$this->name     = _x( 'Multi Select Box', 'xprofile field type', 'buddypress' );
 
+		$this->supports_multiple_values   = true;
 		$this->supports_multiple_defaults = true;
 		$this->accepts_null_value         = true;
 		$this->supports_options           = true;
diff --git a/src/bp-xprofile/classes/class-bp-xprofile-field-type.php b/src/bp-xprofile/classes/class-bp-xprofile-field-type.php
index 65a970c68..66e451df4 100644
--- a/src/bp-xprofile/classes/class-bp-xprofile-field-type.php
+++ b/src/bp-xprofile/classes/class-bp-xprofile-field-type.php
@@ -65,6 +65,14 @@ abstract class BP_XProfile_Field_Type {
 	 */
 	public $supports_options = false;
 
+	/**
+	 * If allowed to store multiple values.
+	 *
+	 * @since 3.0.0
+	 * @var bool Does this field support multiple values? e.g. multiselectbox, checkbox.
+	 */
+	public $supports_multiple_values = false;
+
 	/**
 	 * If allowed to support multiple options as default.
 	 *
diff --git a/src/bp-xprofile/classes/class-bp-xprofile-profiledata.php b/src/bp-xprofile/classes/class-bp-xprofile-profiledata.php
index 62603e7c0..c02201134 100644
--- a/src/bp-xprofile/classes/class-bp-xprofile-profiledata.php
+++ b/src/bp-xprofile/classes/class-bp-xprofile-profiledata.php
@@ -89,9 +89,22 @@ class BP_XProfile_ProfileData {
 			$bp = buddypress();
 
 			$sql         = $wpdb->prepare( "SELECT * FROM {$bp->profile->table_name_data} WHERE field_id = %d AND user_id = %d", $field_id, $user_id );
-			$profiledata = $wpdb->get_row( $sql );
+			$profiledata = $wpdb->get_results( $sql );
 
 			if ( $profiledata ) {
+
+				// If the field supports multiple values, an array should be returned.
+				if ( bp_xprofile_field_supports_multiple_values( $profiledata[0]->field_id ) ) {
+					$profiledata[0]->value = wp_list_pluck( $profiledata, 'value' );
+
+					// Parse empty list
+					if ( array() === maybe_unserialize( $profiledata[0]->value ) ) {
+						$profiledata[0]->value = array();
+					}
+				}
+
+				// Get the first row
+				$profiledata = $profiledata[0];
 				wp_cache_set( $cache_key, $profiledata, 'bp_xprofile_data' );
 			}
 		}
@@ -100,7 +113,7 @@ class BP_XProfile_ProfileData {
 			$this->id           = (int) $profiledata->id;
 			$this->user_id      = (int) $profiledata->user_id;
 			$this->field_id     = (int) $profiledata->field_id;
-			$this->value        = stripslashes( $profiledata->value );
+			$this->value        = is_array( $profiledata->value ) ? array_map( 'stripslashes', $profiledata->value ) : stripslashes( $profiledata->value );
 			$this->last_updated = $profiledata->last_updated;
 
 		} else {
@@ -184,9 +197,47 @@ class BP_XProfile_ProfileData {
 
 		$bp = buddypress();
 
-		$this->user_id      = apply_filters( 'xprofile_data_user_id_before_save',      $this->user_id,         $this->id );
-		$this->field_id     = apply_filters( 'xprofile_data_field_id_before_save',     $this->field_id,        $this->id );
-		$this->value        = apply_filters( 'xprofile_data_value_before_save',        $this->value,           $this->id, true, $this );
+		/**
+		 * Filters the data's user ID before saving to the database.
+		 *
+		 * @since 1.0.0
+		 *
+		 * @param int $user_id The user ID.
+		 * @param int $data_id The field data ID.
+		 */
+		$this->user_id = apply_filters( 'xprofile_data_user_id_before_save', $this->user_id, $this->id );
+
+		/**
+		 * Filters the data's field ID before saving to the database.
+		 *
+		 * @since 1.0.0
+		 *
+		 * @param int $field_id The field ID.
+		 * @param int $data_id  The field data ID.
+		 */
+		$this->field_id = apply_filters( 'xprofile_data_field_id_before_save', $this->field_id, $this->id );
+
+		/**
+		 * Filters the data's value before saving to the database.
+		 *
+		 * @since 1.0.0
+		 * @since 2.1.0 Added `$reserialize` and `$this` parameters.
+		 *
+		 * @param string                  $field_value The field value.
+		 * @param int                     $data_id     The field data ID.
+		 * @param bool                    $reserialize Whether to reserialize arrays before returning. Defaults to true.
+		 * @param BP_XProfile_ProfileData $this        Current instance of the profile data being saved.
+		 */
+		$this->value = apply_filters( 'xprofile_data_value_before_save', $this->value, $this->id, true, $this );
+
+		/**
+		 * Filters the data's last updated timestamp before saving to the database.
+		 *
+		 * @since 1.0.0
+		 *
+		 * @param int $last_updated The last updated timestamp.
+		 * @param int $data_id      The field data ID.
+		 */
 		$this->last_updated = apply_filters( 'xprofile_data_last_updated_before_save', bp_core_current_time(), $this->id );
 
 		/**
@@ -201,14 +252,40 @@ class BP_XProfile_ProfileData {
 		do_action_ref_array( 'xprofile_data_before_save', array( $this ) );
 
 		if ( $this->is_valid_field() ) {
-			if ( $this->exists() && strlen( trim( $this->value ) ) ) {
+
+			// Special-case support for integer 0 for the number field type
+			$value_is_empty = empty( $this->value ) && ! is_integer( $this->value ) && '0' !== $this->value;
+
+			// Store as multiple values
+			if ( $this->exists() && bp_xprofile_field_supports_multiple_values( $this->field_id ) ) {
+
+				// Delete previous rows.
+				$this->delete();
+
+				// Store empty list as serialized array
+				if ( empty( $this->value ) ) {
+					$this->value = array( serialize( array() ) );
+				}
+
+				// Store each value in a separate row
+				foreach ( array_values( (array) $this->value ) as $k => $value ) {
+					$result = $wpdb->query( $wpdb->prepare("INSERT INTO {$bp->profile->table_name_data} (user_id, field_id, value, last_updated) VALUES (%d, %d, %s, %s)", $this->user_id, $this->field_id, $value, $this->last_updated ) );
+
+					// Use the first inserted id as the new data identifier
+					if ( 0 === $k ) {
+						$this->id = $wpdb->insert_id;
+					}
+				}
+
+			// Store as single value
+			} elseif ( $this->exists() && ! $value_is_empty ) {
 				$result   = $wpdb->query( $wpdb->prepare( "UPDATE {$bp->profile->table_name_data} SET value = %s, last_updated = %s WHERE user_id = %d AND field_id = %d", $this->value, $this->last_updated, $this->user_id, $this->field_id ) );
 
-			} elseif ( $this->exists() && empty( $this->value ) ) {
-				// Data removed, delete the entry.
+			// Data removed, delete the entry.
+			} elseif ( $this->exists() && $value_is_empty ) {
 				$result   = $this->delete();
 
-			} else {
+			} elseif ( ! $value_is_empty ) {
 				$result   = $wpdb->query( $wpdb->prepare("INSERT INTO {$bp->profile->table_name_data} (user_id, field_id, value, last_updated) VALUES (%d, %d, %s, %s)", $this->user_id, $this->field_id, $this->value, $this->last_updated ) );
 				$this->id = $wpdb->insert_id;
 			}
@@ -299,14 +376,30 @@ class BP_XProfile_ProfileData {
 			// Rekey.
 			$queried_data = array();
 			foreach ( $uncached_data as $ud ) {
-				$d               = new stdClass;
-				$d->id           = $ud->id;
-				$d->user_id      = $ud->user_id;
-				$d->field_id     = $ud->field_id;
-				$d->value        = $ud->value;
-				$d->last_updated = $ud->last_updated;
-
-				$queried_data[ $ud->field_id ] = $d;
+
+				// Set initial field data
+				if ( ! isset( $queried_data[ $ud->field_id ] ) ) {
+					$d               = new stdClass;
+					$d->id           = $ud->id;
+					$d->user_id      = $ud->user_id;
+					$d->field_id     = $ud->field_id;
+					$d->last_updated = $ud->last_updated;
+
+					// Collect multiple values in array
+					// TODO: no stripslashing here? See ::populate()
+					if ( bp_xprofile_field_supports_multiple_values( $ud->field_id ) ) {
+						$d->value = ( array() === maybe_unserialize( $ud->value ) ) ? array() : array( $ud->value );
+					} else {
+						$d->value = $ud->value;
+					}
+
+					$queried_data[ $ud->field_id ] = $d;
+
+				// Collect multiple values per field
+				} elseif ( bp_xprofile_field_supports_multiple_values( $ud->field_id ) ) {
+					// TODO: no stripslashing here? See ::populate()
+					$queried_data[ $ud->field_id ]->value[] = $ud->value;
+				}
 			}
 
 			// Set caches.
@@ -325,7 +418,7 @@ class BP_XProfile_ProfileData {
 					$d->id           = '';
 					$d->user_id      = $user_id;
 					$d->field_id     = $field_id;
-					$d->value        = '';
+					$d->value        = bp_xprofile_field_supports_multiple_values( $field_id ) ? array() : '';
 					$d->last_updated = '';
 
 					wp_cache_set( $cache_key, $d, 'bp_xprofile_data' );
@@ -405,6 +498,7 @@ class BP_XProfile_ProfileData {
 	 * Get the user's field data id by the id of the xprofile field.
 	 *
 	 * @since 1.6.0
+	 * @since 3.0.0 Returns the first/main data id in case of multiple values.
 	 *
 	 * @param int $field_id Field ID being queried for.
 	 * @param int $user_id  User ID associated with field.
@@ -471,11 +565,28 @@ class BP_XProfile_ProfileData {
 			$bp = buddypress();
 			$uncached_ids_sql = implode( ',', $uncached_ids );
 			$queried_data = $wpdb->get_results( $wpdb->prepare( "SELECT id, user_id, field_id, value, last_updated FROM {$bp->profile->table_name_data} WHERE field_id = %d AND user_id IN ({$uncached_ids_sql})", $field_id ) );
+			$multiple = bp_xprofile_field_supports_multiple_values( $field_id );
 
 			// Rekey.
 			$qd = array();
 			foreach ( $queried_data as $data ) {
-				$qd[ $data->user_id ] = $data;
+
+				// Set initial user data
+				if ( ! isset( $qd[ $data->user_id ] ) ) {
+
+					// Collect multiple values in array
+					if ( $multiple ) {
+						// TODO: no stripslashing here? See ::populate().
+						$data->value = ( array() === maybe_unserialize( $data->value ) ) ? array() : array( $data->value );
+					}
+
+					$qd[ $data->user_id ] = $data;
+
+				// Collect multiple values per field
+				} elseif ( $multiple ) {
+					// TODO: no stripslashing here? See ::populate().
+					$qd[ $data->user_id ]->value[] = $data->value;
+				}
 			}
 
 			foreach ( $uncached_ids as $id ) {
@@ -490,7 +601,7 @@ class BP_XProfile_ProfileData {
 					$d->id           = '';
 					$d->user_id      = $id;
 					$d->field_id     = $field_id;
-					$d->value        = '';
+					$d->value        = $multiple ? array() : '';
 					$d->last_updated = '';
 				}
 
@@ -566,9 +677,10 @@ class BP_XProfile_ProfileData {
 			$field_sql .= $wpdb->prepare( "AND f.name = %s", $fields );
 		}
 
-		$sql    = $wpdb->prepare( "SELECT d.value, f.name FROM {$bp->profile->table_name_data} d, {$bp->profile->table_name_fields} f WHERE d.field_id = f.id AND d.user_id = %d AND f.parent_id = 0 $field_sql", $user_id );
+		$sql    = $wpdb->prepare( "SELECT d.value, f.name, f.id FROM {$bp->profile->table_name_data} d, {$bp->profile->table_name_fields} f WHERE d.field_id = f.id AND d.user_id = %d AND f.parent_id = 0 $field_sql", $user_id );
 		$values = $wpdb->get_results( $sql );
 
+		// TODO: checking for empty result/WP_Error, but not in other methods?
 		if ( empty( $values ) || is_wp_error( $values ) ) {
 			return false;
 		}
@@ -579,14 +691,37 @@ class BP_XProfile_ProfileData {
 			for ( $i = 0, $count = count( $values ); $i < $count; ++$i ) {
 				for ( $j = 0; $j < count( $fields ); $j++ ) {
 					if ( $values[$i]->name == $fields[$j] ) {
-						$new_values[$fields[$j]] = $values[$i]->value;
+						$multiple = bp_xprofile_field_supports_multiple_values( $values[$i]->id );
+
+						// TODO: no stripslashing here? See ::populate()
+						if ( ! isset( $new_values[ $fields[$j] ] ) ) {
+							if ( $multiple ) {
+								$new_values[$fields[$j]] = ( array() === $values[$i]->value ) ? array() : array( $values[$i]->value );
+							} else {
+								$new_values[$fields[$j]] = $values[$i]->value;
+							}
+						} elseif ( $multiple ) {
+							$new_values[$fields[$j]][] = $values[$i]->value;
+						}
 					} elseif ( !array_key_exists( $fields[$j], $new_values ) ) {
 						$new_values[$fields[$j]] = NULL;
 					}
 				}
 			}
 		} else {
-			$new_values = $values[0]->value;
+
+			// Collect multiple values in array
+			// TODO: no stripslashing here? See ::populate()
+			if ( bp_xprofile_field_supports_multiple_values( $values[0]->id ) ) {
+				$new_values = wp_list_pluck( $values, 'value' );
+
+				// Parse empty list
+				if ( array() === maybe_unserialize( $new_values[0] ) ) {
+					$new_values = array();
+				}
+			} else {
+				$new_values = $values[0]->value;
+			}
 		}
 
 		return $new_values;
@@ -651,18 +786,34 @@ class BP_XProfile_ProfileData {
 	 *
 	 * @since 1.0.0
 	 *
-	 * @param int    $user_id          User ID to query for.
-	 * @param string $exclude_fullname SQL portion used to exclude by field ID.
+	 * @param int  $user_id          User ID to query for.
+	 * @param bool $exclude_fullname Optional. Whether to exclude the fullname field. Defaults to false.
 	 * @return array|null|object
 	 */
-	public static function get_random( $user_id, $exclude_fullname ) {
+	public static function get_random( $user_id, $exclude_fullname = false ) {
 		global $wpdb;
 
 		$exclude_sql = ! empty( $exclude_fullname ) ? ' AND pf.id != 1' : '';
 
 		$bp = buddypress();
 
-		return $wpdb->get_results( $wpdb->prepare( "SELECT pf.type, pf.name, pd.value FROM {$bp->profile->table_name_data} pd INNER JOIN {$bp->profile->table_name_fields} pf ON pd.field_id = pf.id AND pd.user_id = %d {$exclude_sql} ORDER BY RAND() LIMIT 1", $user_id ) );
+		$rand_sql = "SELECT id FROM {$bp->profile->table_name_fields} ORDER BY RAND() LIMIT 1";
+		$result   = $wpdb->get_results( $wpdb->prepare( "SELECT pf.type, pf.name, pd.value, pf.id FROM {$bp->profile->table_name_data} pd INNER JOIN {$bp->profile->table_name_fields} pf ON pd.field_id = pf.id AND pd.user_id = %d {$exclude_sql} WHERE pf.id IN ($rand_sql)", $user_id ) );
+
+		// Collect multiple values in array
+		if ( bp_xprofile_field_supports_multiple_values( $result[0]->id ) ) {
+			// TODO: no stripslashing here? See ::populate()
+			$result[0]->value = wp_list_pluck( $result, 'value' );
+
+			// Parse empty list
+			if ( array() === maybe_unserialize( $result[0]->value ) ) {
+				$result[0]->value = array();
+			}
+
+			$result = array( $result[0] );
+		}
+
+		return $result;
 	}
 
 	/**
