<blockquote>
<p><strong>Edit:</strong> I've misunderstood the question! It sounds like Schools aren't related Elements, but just a dropdown value?</p>
</blockquote>
<hr />
<p>I think there are a couple of missteps, here:</p>
<ol>
<li>The <code>.group()</code> <em>method</em> on a <code>UserQuery</code> actually applies a filter, narrowing the results by a User Group with that handle. (Maybe that's understood, but I wanted to note the difference between this and the next couple of notes!)</li>
<li>(An aside that will help optimize this for #3) I recommend eager-loading your related School elements by calling <code>.with(['schoolAttended'])</code> on your main User query.</li>
<li>The <code>| group(…)</code> <em>filter</em> takes an array and groups it by a property, closure, or Twig expression. In this case, I think you actually want to be more explicit about how the grouping is happening, so I'd use <code>| group(u =&gt; (u.schoolAttended | first).id)</code>. This ensures the key used for grouping is consistent and unique.</li>
<li><code>usersBySchool.all()</code> is calling the <code>.all()</code> method on an array, which won't work (it'll only be present on <code>ElementQuery</code> instances)—your Elements are already loaded after the first statement, and grouping just takes the resulting array and re-organizes it! This <code>for</code> loop should probably just be: <code>{% for schoolId, athletes in usersBySchool %} … {% endfor %}</code>.</li>
</ol>
<p>So, altogether:</p>
<pre><code>{# Load all “athlete” users: #}
{% set athletes = craft.users({
  group: 'athlete',
  with: ['schoolAttended']
}).all() %}

{# Group by their School's ID: #}
{% set athletesBySchoolId = athletes | group((u) =&gt; (u.schoolAttended | first).id) %}

{# Fetch Schools and index by ID. Note that we have the IDs ready, via the grouping operation, above—we can just take the keys off that array! #}
{% set schoolsById = craft.entries({
  section: 'schools',
  indexBy: 'id',
  id: athletesBySchoolId | keys
}).all() %}

{% for schoolId, athletes in athletesBySchoolId %}
  {# Look up the school for this group via our secondary Schools query (which, again, is indexed by ID): #}
  {% set school = schoolsById[schoolId] %}

  &lt;h1&gt;{{ school.title }}&lt;/h1&gt;
  &lt;ul&gt;
    {% for athlete in athletes %}
      &lt;li&gt;{{ athlete.getFullName() }}&lt;/li&gt;
    {% endfor %}
  &lt;/ul&gt;
{% endfor %} 
</code></pre>

CC BY-SA 4.0
2020-08-15T22:46:50.313Z
@CynderGray I'll submit a new answer, then. 
August Miller
CC BY-SA 4.0
2020-08-15T21:20:16.730Z
2020-08-15T21:20:16.730Z
August Miller
<p>Apologies to the community for doubling-up on Answers. OP clarified that indeed they were looking to group based on a Dropdown field, which changes the approach somewhat (and side-steps any eager-loading/nested querying).</p>
<p>Let's see if we can't simplify things. The most important thing to keep in mind in this model is that Dropdown values are stored as simple strings in the database, then “hydrated” with the context of the Dropdown field (i.e. the corresponding Label for that option's <code>value</code>), when populating an Element.</p>
<pre><code>{# Load all “athlete” users: #}
{% set athletes = craft.users({
  group: 'athlete'
}).all() %}

{# Group by School dropdown `value` (I'm interjecting a preference here, which is to use a closure for grouping, instead of letting the Field get automatically coerced—which in this case actually results in the keys human-readable labels, not the actual stored values): #}
{% athletesBySchool = athletes | group((a) =&gt; a.schoolAttended.value) %}

{# Get School options from the Field definition, indexing by `value`: #}
{% set schools = craft.app.fields.getFieldByHandle('schoolAttended').options | index('value') %}

{# This results in a structure like this:
   {
     schoolName: {
       value: 'schoolName',
       label: 'School Name'
     },
     ...
   }
#}

{% for schoolKey, athletes in athletesBySchool %}
  {# Look up the school for this group among our field's options: #}
  {% set school = schools[schoolKey] %}

  &lt;h1&gt;{{ school.label }}&lt;/h1&gt;
  &lt;ul&gt;
    {% for athlete in athletes %}
      &lt;li&gt;{{ athlete.getFullName() }}&lt;/li&gt;
    {% endfor %}
  &lt;/ul&gt;
{% endfor %} 
</code></pre>

CC BY-SA 4.0
2020-08-15T23:07:35.050Z
2020-08-15T23:07:35.050Z
August Miller
<p>I have a list of students and can sort them by name, sport, and school. The name and sport portions are easy, I'm grabbing the values without issue.  Where I'm struggling is the school value is from a Dropdown field.
Using the following code results in no students being listed let alone being sorted by school.</p>
<pre><code>   {% set usersSchoolQuery = craft.users().group('athlete').all() %}
   {% set usersBySchool = usersSchoolQuery|group('schoolAttended.one()') %}
   {% for users in usersBySchool.all() %}
   {% for user in users %} 
</code></pre>
<p>This should work but isn't. Could someone see where I'm going wrong here?</p>

CC BY-SA 4.0
2020-08-15T21:23:33.383Z
Maybe ignore my "answer" below, for a moment. I relied too much on the code snippet, which implies your `schoolAttended` field is a relational field (as though Schools were Entries). If it's indeed a Dropdown field with a static set of options, then you should be able to just do `craft.users().group('athlete').order('schoolAttended')`. Keep in mind that grouping and ordering have different effects!
August Miller
<templating><craft3><forloop><drop-down>
Sort Entries by Value from Dropdown
# Sort Entries by Value from Dropdown

(Asked by: username_0 on 2020-08-15)

I have a list of students and can sort them by name, sport, and school. The name and sport portions are easy, I'm grabbing the values without issue.  Where I'm struggling is the school value is from a Dropdown field.
Using the following code results in no students being listed let alone being sorted by school.
   {% set usersSchoolQuery = craft.users().group('athlete').all() %}
   {% set usersBySchool = usersSchoolQuery|group('schoolAttended.one()') %}
   {% for users in usersBySchool.all() %}
   {% for user in users %} 

This should work but isn't. Could someone see where I'm going wrong here?

**Tags:** templating, craft3, forloop, drop-down
> **Comments:**
> **username_1**: Maybe ignore my "answer" below, for a moment. I relied too much on the code snippet, which implies your `schoolAttended` field is a relational field (as though Schools were Entries). If it's indeed a Dropdown field with a static set of options, then you should be able to just do `craft.users().group('athlete').order('schoolAttended')`. Keep in mind that grouping and ordering have different effects!  

---

## 2 answers

### Answer by username_1 on 2020-08-15. Score: 1

Edit: I've misunderstood the question! It sounds like Schools aren't related Elements, but just a dropdown value?


I think there are a couple of missteps, here:

The .group() method on a UserQuery actually applies a filter, narrowing the results by a User Group with that handle. (Maybe that's understood, but I wanted to note the difference between this and the next couple of notes!)
(An aside that will help optimize this for #3) I recommend eager-loading your related School elements by calling .with(['schoolAttended']) on your main User query.
The | group(…) filter takes an array and groups it by a property, closure, or Twig expression. In this case, I think you actually want to be more explicit about how the grouping is happening, so I'd use | group(u => (u.schoolAttended | first).id). This ensures the key used for grouping is consistent and unique.
usersBySchool.all() is calling the .all() method on an array, which won't work (it'll only be present on ElementQuery instances)—your Elements are already loaded after the first statement, and grouping just takes the resulting array and re-organizes it! This for loop should probably just be: {% for schoolId, athletes in usersBySchool %} … {% endfor %}.

So, altogether:
{# Load all “athlete” users: #}
{% set athletes = craft.users({
  group: 'athlete',
  with: ['schoolAttended']
}).all() %}

{# Group by their School's ID: #}
{% set athletesBySchoolId = athletes | group((u) => (u.schoolAttended | first).id) %}

{# Fetch Schools and index by ID. Note that we have the IDs ready, via the grouping operation, above—we can just take the keys off that array! #}
{% set schoolsById = craft.entries({
  section: 'schools',
  indexBy: 'id',
  id: athletesBySchoolId | keys
}).all() %}

{% for schoolId, athletes in athletesBySchoolId %}
  {# Look up the school for this group via our secondary Schools query (which, again, is indexed by ID): #}
  {% set school = schoolsById[schoolId] %}

  {{ school.title }}
  
    {% for athlete in athletes %}
      {{ athlete.getFullName() }}
    {% endfor %}
  
{% endfor %}

> **Comments:**
> **username_1**: @CynderGray I'll submit a new answer, then.   

---

### Answer by username_1 on 2020-08-15. Score: 1

Apologies to the community for doubling-up on Answers. OP clarified that indeed they were looking to group based on a Dropdown field, which changes the approach somewhat (and side-steps any eager-loading/nested querying).
Let's see if we can't simplify things. The most important thing to keep in mind in this model is that Dropdown values are stored as simple strings in the database, then “hydrated” with the context of the Dropdown field (i.e. the corresponding Label for that option's value), when populating an Element.
{# Load all “athlete” users: #}
{% set athletes = craft.users({
  group: 'athlete'
}).all() %}

{# Group by School dropdown `value` (I'm interjecting a preference here, which is to use a closure for grouping, instead of letting the Field get automatically coerced—which in this case actually results in the keys human-readable labels, not the actual stored values): #}
{% athletesBySchool = athletes | group((a) => a.schoolAttended.value) %}

{# Get School options from the Field definition, indexing by `value`: #}
{% set schools = craft.app.fields.getFieldByHandle('schoolAttended').options | index('value') %}

{# This results in a structure like this:
   {
     schoolName: {
       value: 'schoolName',
       label: 'School Name'
     },
     ...
   }
#}

{% for schoolKey, athletes in athletesBySchool %}
  {# Look up the school for this group among our field's options: #}
  {% set school = schools[schoolKey] %}

  {{ school.label }}
  
    {% for athlete in athletes %}
      {{ athlete.getFullName() }}
    {% endfor %}
  
{% endfor %}


---

