Si vous utilisez AdonisJS et que vous avez des ID mixtes tels que ABC-202, ABC-201 ..., vous pouvez combiner des requêtes brutes avec Query Builder et implémenter la solution ci-dessus ( https://stackoverflow.com/a/25061144/4040835 ) comme suit:
const sortField =
  'membership_id'
const sortDirection =
  'asc'
const subquery = UserProfile.query()
  .select(
    'user_profiles.id',
    'user_profiles.user_id',
    'user_profiles.membership_id',
    'user_profiles.first_name',
    'user_profiles.middle_name',
    'user_profiles.last_name',
    'user_profiles.mobile_number',
    'countries.citizenship',
    'states.name as state_of_origin',
    'user_profiles.gender',
    'user_profiles.created_at',
    'user_profiles.updated_at'
  )
  .leftJoin(
    'users',
    'user_profiles.user_id',
    'users.id'
  )
  .leftJoin(
    'countries',
    'user_profiles.nationality',
    'countries.id'
  )
  .leftJoin(
    'states',
    'user_profiles.state_of_origin',
    'states.id'
  )
  .orderByRaw(
    `SUBSTRING(:sortField:,3,15)*1 ${sortDirection}`,
    {
      sortField: sortField,
    }
  )
  .paginate(
    page,
    per_page
  )
NOTES:  
Dans cette ligne: SUBSTRING(:sortField:,3,15)*1 ${sortDirection},
- «3» représente le numéro d'index du dernier caractère non numérique avant les chiffres. Si votre ID mixte est «ABC-123», votre numéro d'index sera 4.
- «15» est utilisé pour capturer autant de chiffres que possible après le trait d'union.
- «1» exécute une opération mathématique sur la sous-chaîne qui convertit efficacement la sous-chaîne en un nombre.
Réf 1: Vous pouvez en savoir plus sur les liaisons de paramètres dans les requêtes brutes ici: https://knexjs.org/#Raw-Bindings 
Réf 2: Adonis Raw Queries: https://adonisjs.com/docs/4.1/query-builder# _raw_queries