<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Sort UpdateCursor with Multiple SQL ORDER BY Statements? in Python Questions</title>
    <link>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114070#M62897</link>
    <description>&lt;P&gt;how about this: Adding the UpdateCursor based on the OBJECTID of your first sorted()&lt;/P&gt;&lt;LI-CODE lang="python"&gt;fields = ['OBJECTID','GROUPT', 'LABELT','SHAPE@X','SHAPE@Y']
where = f"""GROUPT IS NOT NULL AND TRIM(BOTH ' ' FROM GROUPT) &amp;lt;&amp;gt; ''"""
print(where)
sql_clause = (None, 'ORDER BY GROUPT DESC')
i=0
with arcpy.da.UpdateCursor(fc, fields, where, sql_clause=sql_clause) as ucurs:
    ucursSort = sorted(ucurs,key=lambda group : group[4], reverse=True)
    for group in ucursSort:
        print(group)
        current_group = group
        try:
            if current_group != previous_group:
                letter_index = 0
        except NameError:
            letter_index = 0

        new_lbl = ascii_uppercase[letter_index]
        print(new_lbl)
        
        #ucursSort.updateRow(group)
        where2 = f"""OBJECTID = """+str(group[0])
        print(where2)
        with arcpy.da.UpdateCursor(fc, fields, where2) as ucursU:
            for r in ucursU:
                print(r)
                r[2] = new_lbl
                ucursU.updateRow(r)
            
        letter_index += 1
        previous_group = current_group
        print("------------------")&lt;/LI-CODE&gt;</description>
    <pubDate>Thu, 04 Nov 2021 14:43:18 GMT</pubDate>
    <dc:creator>DominicRobergeIADOT</dc:creator>
    <dc:date>2021-11-04T14:43:18Z</dc:date>
    <item>
      <title>Sort UpdateCursor with Multiple SQL ORDER BY Statements?</title>
      <link>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1113877#M62889</link>
      <description>&lt;P&gt;I am trying to loop through an existing point feature class with an UpdateCursor (DA version) and assign consecutive labels (A, B, C, D...) to a field for features that fall within the same "group," which is a numbered attribute stored in another field. Lets call them the GROUP field and the LABEL field.&lt;/P&gt;&lt;P&gt;I have accomplished this as follows, and it seems to work fine. It uses SQL's "ORDER BY GROUP," then increments through an alphabet string to assign the LABEL, then starts over at 'A' when the GROUP changes.&lt;/P&gt;&lt;LI-CODE lang="python"&gt;from string import ascii_uppercase
from arcpy.da import UpdateCursor

fc = r'C:\Users\vce50\Desktop\Cursors\Cursors\Cursors.gdb\Random_Points'
fields = ['GRP', 'LBL']
where = f"""GRP IS NOT NULL AND TRIM(BOTH ' ' FROM GRP) &amp;lt;&amp;gt; ''"""
sql_clause = (None, 'ORDER BY GRP ASC')

with UpdateCursor(fc, fields, where, sql_clause=sql_clause) as ucurs:
    for group, _ in ucurs:
        current_group = group
        try:
            if current_group != previous_group:
                letter_index = 0
        except NameError:
            letter_index = 0

        new_lbl = ascii_uppercase[letter_index]
        ucurs.updateRow([group, new_lbl])

        letter_index += 1
        previous_group = current_group&lt;/LI-CODE&gt;&lt;P&gt;The problem is that I would also like to order the labels spatially (north to south, for example), as a secondary sort after the GROUP. I am using a File GDB feature class, so I think that means no spatial SQL queries. I have also tried adding a Y_COOR field (DOUBLE type), and using that as a secondary SQL ORDER BY:&lt;/P&gt;&lt;LI-CODE lang="python"&gt;sql_clause = (None, f"""ORDER BY {grp_fld} ASC; ORDER BY {y_coor} DESC""")&lt;/LI-CODE&gt;&lt;P&gt;However, I cannot seem to get this to work. It seems like only one ORDER BY query can be passed. Is that the case?&lt;/P&gt;&lt;P&gt;I would prefer to do this in place with an UpdateCursor, but could also read all rows using a SearchCursor, sort with Python's sorted() and lambda function to order by multiple fields, and then write rows to a new blank feature class if the UpdateCursor won't work. Any recommendations would be appreciated!&lt;/P&gt;</description>
      <pubDate>Thu, 04 Nov 2021 00:40:55 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1113877#M62889</guid>
      <dc:creator>VinceE</dc:creator>
      <dc:date>2021-11-04T00:40:55Z</dc:date>
    </item>
    <item>
      <title>Re: Sort UpdateCursor with Multiple SQL ORDER BY Statements?</title>
      <link>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114046#M62890</link>
      <description>&lt;P&gt;Looks like this was a very clear issue of bad syntax on my part... here is sorting by three fields (all ascending, by default), by priority, in case someone else stumbles across this issue.&lt;/P&gt;&lt;LI-CODE lang="python"&gt;sql_clause = (None, f"""ORDER BY {grp_fld}, {agency_fld}, {xcoor_fld}""")&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 04 Nov 2021 13:50:57 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114046#M62890</guid>
      <dc:creator>VinceE</dc:creator>
      <dc:date>2021-11-04T13:50:57Z</dc:date>
    </item>
    <item>
      <title>Re: Sort UpdateCursor with Multiple SQL ORDER BY Statements?</title>
      <link>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114053#M62891</link>
      <description>&lt;P&gt;Hi Vince&lt;/P&gt;&lt;P&gt;would this work for you. I tested it and seems like the sorted() reverse=true on the &lt;A href="mailto:SHAPE@Y" target="_blank"&gt;SHAPE@Y&lt;/A&gt;&amp;nbsp;field will sort from North to South&lt;/P&gt;&lt;LI-CODE lang="python"&gt;fields = ['OBJECTID','GROUPT', 'LABELT','SHAPE@X','SHAPE@Y']
where = f"""GROUPT IS NOT NULL AND TRIM(BOTH ' ' FROM GROUPT) &amp;lt;&amp;gt; ''"""
sql_clause = (None, 'ORDER BY GROUPT DESC')

with arcpy.da.UpdateCursor(fc, fields, where, sql_clause=sql_clause) as ucurs:
    ucursSort = sorted(ucurs,key=lambda group : group[4], reverse=True)
    for group in ucursSort:
        print(group)
        current_group = group
        try:
            if current_group != previous_group:
                letter_index = 0
        except NameError:
            letter_index = 0

        new_lbl = ascii_uppercase[letter_index]
        #ucurs.updateRow([group, new_lbl])

        letter_index += 1
        previous_group = current_group&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 04 Nov 2021 14:05:17 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114053#M62891</guid>
      <dc:creator>DominicRobergeIADOT</dc:creator>
      <dc:date>2021-11-04T14:05:17Z</dc:date>
    </item>
    <item>
      <title>Re: Sort UpdateCursor with Multiple SQL ORDER BY Statements?</title>
      <link>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114061#M62893</link>
      <description>&lt;P&gt;Commenting out the updateRow line effectively turns the UpdateCursor into a SearchCursor.&amp;nbsp; That said, uncommenting the updateRow line won't work because the update cursor has been fully iterated by sorted so there is no current row to update.&lt;/P&gt;</description>
      <pubDate>Thu, 04 Nov 2021 14:16:51 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114061#M62893</guid>
      <dc:creator>JoshuaBixby</dc:creator>
      <dc:date>2021-11-04T14:16:51Z</dc:date>
    </item>
    <item>
      <title>Re: Sort UpdateCursor with Multiple SQL ORDER BY Statements?</title>
      <link>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114069#M62896</link>
      <description>&lt;P&gt;Thanks for the input! This is close to the approach I would have used had I not gotten my SQL syntax sorted out, but &lt;a href="https://community.esri.com/t5/user/viewprofilepage/user-id/1371"&gt;@JoshuaBixby&lt;/a&gt;'s comments would be issues with the Cursor.&lt;/P&gt;&lt;P&gt;I think I would have had to use a SearchCursor, use sorted() with a lambda function (as you have done), and then use a separate &lt;STRIKE&gt;UpdateCursor&lt;/STRIKE&gt;&amp;nbsp;InsertCursor to write the sorted rows to a blank feature class with the same schema. Probably workable, but involves iterating over the same data&amp;nbsp;more times&amp;nbsp;(three total?) than necessary.&lt;/P&gt;</description>
      <pubDate>Thu, 04 Nov 2021 14:44:30 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114069#M62896</guid>
      <dc:creator>VinceE</dc:creator>
      <dc:date>2021-11-04T14:44:30Z</dc:date>
    </item>
    <item>
      <title>Re: Sort UpdateCursor with Multiple SQL ORDER BY Statements?</title>
      <link>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114070#M62897</link>
      <description>&lt;P&gt;how about this: Adding the UpdateCursor based on the OBJECTID of your first sorted()&lt;/P&gt;&lt;LI-CODE lang="python"&gt;fields = ['OBJECTID','GROUPT', 'LABELT','SHAPE@X','SHAPE@Y']
where = f"""GROUPT IS NOT NULL AND TRIM(BOTH ' ' FROM GROUPT) &amp;lt;&amp;gt; ''"""
print(where)
sql_clause = (None, 'ORDER BY GROUPT DESC')
i=0
with arcpy.da.UpdateCursor(fc, fields, where, sql_clause=sql_clause) as ucurs:
    ucursSort = sorted(ucurs,key=lambda group : group[4], reverse=True)
    for group in ucursSort:
        print(group)
        current_group = group
        try:
            if current_group != previous_group:
                letter_index = 0
        except NameError:
            letter_index = 0

        new_lbl = ascii_uppercase[letter_index]
        print(new_lbl)
        
        #ucursSort.updateRow(group)
        where2 = f"""OBJECTID = """+str(group[0])
        print(where2)
        with arcpy.da.UpdateCursor(fc, fields, where2) as ucursU:
            for r in ucursU:
                print(r)
                r[2] = new_lbl
                ucursU.updateRow(r)
            
        letter_index += 1
        previous_group = current_group
        print("------------------")&lt;/LI-CODE&gt;</description>
      <pubDate>Thu, 04 Nov 2021 14:43:18 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114070#M62897</guid>
      <dc:creator>DominicRobergeIADOT</dc:creator>
      <dc:date>2021-11-04T14:43:18Z</dc:date>
    </item>
    <item>
      <title>Re: Sort UpdateCursor with Multiple SQL ORDER BY Statements?</title>
      <link>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114080#M62898</link>
      <description>&lt;P&gt;I am guessing nesting update cursors on the same feature class will create lock issues that prevent the nested cursor from actually updating.&amp;nbsp; Have you tested this and it worked?&lt;/P&gt;</description>
      <pubDate>Thu, 04 Nov 2021 14:59:31 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114080#M62898</guid>
      <dc:creator>JoshuaBixby</dc:creator>
      <dc:date>2021-11-04T14:59:31Z</dc:date>
    </item>
    <item>
      <title>Re: Sort UpdateCursor with Multiple SQL ORDER BY Statements?</title>
      <link>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114081#M62899</link>
      <description>&lt;P&gt;I did tested it on a point feature class in a file geodatabase and it worked for me&lt;/P&gt;</description>
      <pubDate>Thu, 04 Nov 2021 15:00:49 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114081#M62899</guid>
      <dc:creator>DominicRobergeIADOT</dc:creator>
      <dc:date>2021-11-04T15:00:49Z</dc:date>
    </item>
    <item>
      <title>Re: Sort UpdateCursor with Multiple SQL ORDER BY Statements?</title>
      <link>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114085#M62902</link>
      <description>&lt;P&gt;Interesting, I don't nest update cursors on the same dataset, but I will have to test it out sometime.&lt;/P&gt;</description>
      <pubDate>Thu, 04 Nov 2021 15:03:18 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114085#M62902</guid>
      <dc:creator>JoshuaBixby</dc:creator>
      <dc:date>2021-11-04T15:03:18Z</dc:date>
    </item>
    <item>
      <title>Re: Sort UpdateCursor with Multiple SQL ORDER BY Statements?</title>
      <link>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114090#M62903</link>
      <description>&lt;P&gt;we could replace the first updateCursor with SearchCursor, it's still working for me&lt;/P&gt;&lt;LI-CODE lang="python"&gt;fields = ['OBJECTID','GROUPT', 'LABELT','SHAPE@X','SHAPE@Y']
where = f"""GROUPT IS NOT NULL AND TRIM(BOTH ' ' FROM GROUPT) &amp;lt;&amp;gt; ''"""
print(where)
sql_clause = (None, 'ORDER BY GROUPT DESC')
i=0
with arcpy.da.SearchCursor(fc, fields, where, sql_clause=sql_clause) as ucurs:
    ucursSort = sorted(ucurs,key=lambda group : group[4], reverse=True)
    for group in ucursSort:
        print(group)
        current_group = group
        try:
            if current_group != previous_group:
                letter_index = 0
        except NameError:
            letter_index = 0

        new_lbl = ascii_uppercase[letter_index]
        print(new_lbl)
        
        #ucursSort.updateRow(group)
        where2 = f"""OBJECTID = """+str(group[0])
        print(where2)
        with arcpy.da.UpdateCursor(fc, fields, where2) as ucursU:
            for r in ucursU:
                print(r)
                r[2] = new_lbl
                ucursU.updateRow(r)
            
        letter_index += 1
        previous_group = current_group
        print("------------------")&lt;/LI-CODE&gt;</description>
      <pubDate>Thu, 04 Nov 2021 15:09:27 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114090#M62903</guid>
      <dc:creator>DominicRobergeIADOT</dc:creator>
      <dc:date>2021-11-04T15:09:27Z</dc:date>
    </item>
    <item>
      <title>Re: Sort UpdateCursor with Multiple SQL ORDER BY Statements?</title>
      <link>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114260#M62908</link>
      <description>&lt;P&gt;This is great, thanks for sharing this. For the fun of it, I rewrote to avoid using the nested cursors. I think a lot of this is a matter of style/opinion, but this separates the reading and editing from the writing, and also only sorts using the lambda function, rather than once with the SQL query and once with the lambda.&lt;/P&gt;&lt;P&gt;It's basically the same as yours, it just creates a dictionary of updated values with the OID as the key, which enables writing in the correct order. This only uses two cursors (I believe you are recreating an UpdateCursor with every SearchCursor loop--I don't know how expensive that is). However, this version does have to create the intermediate dictionary.&lt;/P&gt;&lt;P&gt;While I still think using the SQL query could be cleaner/easier to read, I assume it is slower because it forces the user to add and calculate a separate coordinate field (unless they have a spatially enabled geodatabase). Because the spirit of the question was specifically about using the SQL query, I am going to leave that as marked correct for posterity, but thanks all the input!&lt;/P&gt;&lt;LI-CODE lang="python"&gt;from string import ascii_uppercase
from arcpy.da import SearchCursor, UpdateCursor

fc = r'PATH'

# Ensure OID and SHAPE are index 0 and 1.
fld = [f.name for f in ap.ListFields(fc) if f.type not in ['Geometry', 'OID']]
all_fld = [ap.da.Describe(fc)['OIDFieldName'], 'SHAPE@'] + fld
# ['OBJECTID', 'SHAPE@', 'LBL', 'XCOOR', 'YCOOR', 'GRP']

# Indices of fields, used to call specific values in cursor rows.
grp_idx = all_fld.index('GRP')
lbl_idx = all_fld.index('LBL')

# SQL WHERE:
where = f"""GRP IS NOT NULL AND TRIM(BOTH ' ' FROM GRP) &amp;lt;&amp;gt; ''"""

# Use Python sorted w/ lambda funct; update the given row; store in dict w/ OID key.
# Sort by GROUP, then DESC x-coor.
row_dict = {}
with SearchCursor(fc, all_fld, where) as scurs:
    scurs_sort = sorted(scurs, key=lambda x: (x[grp_idx], -x[1].centroid.X))
    for row in scurs_sort:
        row = list(row)     # Can't update SCurs tuple, unlike UCurs list
        current_group = row[grp_idx]
        try:
            if current_group != previous_group:
                letter_index = 0
        except NameError:
            letter_index = 0

        row[lbl_idx] = ascii_uppercase[letter_index]
        row_dict[row[0]] = row[1:]
        
        letter_index += 1
        previous_group = current_group

# Write the new row back to the same FC, using the OID as key again.
with UpdateCursor(fc, all_fld, where) as ucurs:
    for oid, *_ in ucurs:
        new_data = row_dict[oid]
        ucurs.updateRow([oid, *new_data])&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 04 Nov 2021 19:29:46 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114260#M62908</guid>
      <dc:creator>VinceE</dc:creator>
      <dc:date>2021-11-04T19:29:46Z</dc:date>
    </item>
    <item>
      <title>Re: Sort UpdateCursor with Multiple SQL ORDER BY Statements?</title>
      <link>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114265#M62909</link>
      <description>&lt;P&gt;To follow up with this, I have had luck simultaneously using an UpdateCursor and an InsertCursor on the same feature class. I had a field with a list of values in it, and I needed to explode that list out so each item was in a single row with it's own point. This meant updating the current row to include only the first value in the list, and then creating new rows in the same feature class for each subsequent value in the list.&lt;/P&gt;&lt;P&gt;Using the Editor class enabled me to do this. I don't know exactly what makes this necessary, but I was not able to do it without the Editor.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;with ap.da.Editor(outgdb):
    with UpdateCursor(infc, '*') as ucurs, InsertCursor(infc, '*') as icurs:&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 04 Nov 2021 19:38:28 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/sort-updatecursor-with-multiple-sql-order-by/m-p/1114265#M62909</guid>
      <dc:creator>VinceE</dc:creator>
      <dc:date>2021-11-04T19:38:28Z</dc:date>
    </item>
  </channel>
</rss>

