In \/blogs\/tilting\/2016\/09\/27\/performance-at-a-price-file-geodatabases-and-sql-support?sr=search&searchId=c3a45d0d-24f6-481b-bcf7-cfc7493b25fc&searchIndex=0<\/A>, breng ik de aandacht op de SQL-ondersteuning trade-off die Esri maakte tijdens de ontwikkeling van de file geodatabase (FGDB) als vervanging voor de personal geodatabase (PGDB). In die post worden verschillende links gegeven voor degenen die meer willen weten over SQL-ondersteuning in file geodatabases. Hoewel er veel overlap is in inhoud tussen de verschillende bronnen\/links, zijn er ook belangrijke uitspraken die slechts op één plek bestaan, en dat te weten kan belangrijk zijn bij het oplossen van fouten of het proberen te begrijpen van vreemde resultaten uit gegevens opgeslagen in file geodatabases.<\/P><\/P>Een gebied waar gebruikers zichzelf in de problemen kunnen brengen met file geodatabases en SQL is de EXISTS-voorwaarde of operator. Als je kijkt naar de SQL Reference (FileGDB_SQL.htm) in de File Geodatabase API ( @Esri Downloads <\/A>) of de SQL reference for query expressions used in ArcGIS<\/A>:<\/P>[NOT] EXISTS<\/P><\/TD>Geeft TRUE terug als de subquery ten minste één record retourneert, anders geeft het FALSE terug. Bijvoorbeeld, deze expressie geeft TRUE terug als het OBJECTID-veld een waarde van 50 bevat:<\/P>EXISTS (SELECT * FROM parcels WHERE "OBJECTID" = 50)<\/PRE>EXISTS wordt alleen ondersteund in file, personal en ArcSDE geodatabases.<\/TD><\/TR><\/TBODY><\/TABLE><\/BLOCKQUOTE><\/P>Aangezien SQL EXISTS wordt ondersteund in de file geodatabase, hoe kan iemand dan toch problemen krijgen bij het gebruik ervan? Helaas is het makkelijker dan je zou verwachten, en het antwoord ligt bij gecorreleerde subqueries.<\/P><\/P>Gecorreleerde subqueries zijn vrij gebruikelijk bij het werken met EXISTS, eigenlijk zo gebruikelijk dat Microsoft's EXISTS (Transact-SQL)<\/A> documentatie en Oracle's EXISTS Condition <\/A>documentatie beide een gecorreleerde subquery gebruiken in tenslotte eén codevoorbeeld. In zijn eenvoudigste vorm is een gecorreleerde subquery een subquery die terugverwijst naar één of meer tabellen in de buitenste query. De theorie en empirische kennis van gecorreleerde subqueries gaat veel verder dan deze blogpost, maar ik zal vermelden dat gecorreleerde subqueries enkele JOIN-achtige eigenschappen hebben, of tenminste zo lijken.<\/P><\/P>Het volgende voorbeeld is aangepast van Select Max value arcpy<\/A>, dezelfde GeoNet-vraag die me maanden geleden aanzette tot onderzoek naar dit probleem. Laten we beginnen met 2 basistabellen (TableA en TableB), ieder met een tekst- en een geheel getalveld, en eén tabel bevat een subset van records uit de andere tabel.<\/P><\/P><\/P>>><\/SPAN>><\/SPAN> fgdb =<\/SPAN> # pad naar file geodatabase<\/SPAN>\n>><\/SPAN>><\/SPAN> pgdb =<\/SPAN> # pad naar personal geodatabase<\/SPAN>\n>><\/SPAN>><\/SPAN> egdb =<\/SPAN> # pad naar enterprise geodatabase, SQL Server gebruikt in voorbeeld<\/SPAN>\n>><\/SPAN>><\/SPAN> gpkg =<\/SPAN> # pad naar GeoPackage<\/SPAN>\n>><\/SPAN>><\/SPAN> gdbs =<\/SPAN> (<\/SPAN>fgdb, pgdb, egdb, gpkg)<\/SPAN>\n>><\/SPAN>><\/SPAN> \n>><\/SPAN>><\/SPAN> values =<\/SPAN> (<\/SPAN>(<\/SPAN>"A"<\/SPAN>, 1<\/SPAN>)<\/SPAN>, )<\/SPAN>:<\/SPAN>.<\/SPAN>.<\/SPAN>.<\/SPAN> table =<\/SPAN> arcpy.<\/SPAN>CreateTable_management(<\/SPAN>gdb, <\/SPAN>table_names[<\/SPAN>i-1<\/SPAN>]<\/SPAN>)<\/SPAN>.<\/SPAN>.<\/SPAN>.<\/SPAN> arcpy.<\/SPAN>AddField_management(<\/SPAN>table, <\/SPAN>"id"<\/SPAN>, <\/SPAN>"TEXT"<\/SPAN>)<\/SPAN>.<\/SPAN>.<\/SPAN>.<\/SPAN> arcpy.<\/SPAN>AddField_management(<\/SPAN>table, <\/SPAN>"version"<\/SPAN>, <\/SPAN>"LONG"<\/SPAN>)<\/SPAN> .<\/SPAN>.<\/span>.<\/span> with<\/span> arcpy. < / Span > da < Span Class = "Punctuation Token ">. < / Span > InsertCursor < Span Class = "Punctuation Token ">( < / Span > table < Span Class = "Punctuation Token ">, < / Span > ( < Span Class = "String Token "> "id" < / Span > , < Span Class = "String Token "> "version" < / Span > ) < Span Class = "Punctuation Token ">) < / Span > < span Class = "Keyword Token ">as< / span > cur < span Class = "Punctuation Token ">: < / span >. < / span > < span Class = "Punctuation Token ">. < / span > < span Class = "Punctuation Token ">. < / span >& nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; cur.insertRow(value). < / span > < span Class = "Punctuation Token ">. < / span > < span Class = "Punctuation Token ">. < / span >& nbsp ; & nbsp ; & nbsp ; & nbsp ;. < / span > < span Class = "Punctuation Token ">. < / span > < span Class = "Punctuation Token ">. < / span >& nbsp ; & nbsp ; & nbsp ; & nbsp ; qry = ( < span Class = "String Token "> "BESTAAT (SELECT 1" . . . & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; " VAN TableB". . . & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; " WAAR TableB.id = TableA.id". . . & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp;Opmerking:<\/H5>Coverages, shapefiles en andere niet-geodatabase op bestanden gebaseerde gegevensbronnen ondersteunen geen subqueries. Subqueries die worden uitgevoerd op versioned ArcSDE feature classes en tabellen zullen geen features retourneren die zijn opgeslagen in de delta-tabellen. File geodatabases bieden de beperkte ondersteuning voor subqueries die in deze sectie wordt uitgelegd, terwijl personal en ArcSDE geodatabases volledige ondersteuning bieden. Voor informatie over de volledige set subquery-mogelijkheden van personal en ArcSDE geodatabases, raadpleeg uw DBMS-documentatie.<\/P><\/DIV><\/P><\/P><\/P><\/P>Een subquery is een query genest binnen een andere query. Het kan worden gebruikt om predicate- of aggregatiefuncties toe te passen of om gegevens te vergelijken met waarden die in een andere tabel zijn opgeslagen....<\/P><\/BLOCKQUOTE><\/P>Subquery-ondersteuning in file geodatabases is beperkt tot het volgende:<\/P>IN-predicate. Bijvoorbeeld:<\/LI><\/UL>"COUNTRY_NAME" NOT IN (SELECT "COUNTRY_NAME" FROM indep_countries)<\/PRE>Scalaire subqueries met vergelijkingsoperatoren. Een scalaire subquery retourneert een enkele waarde. Bijvoorbeeld:<\/LI><\/UL>"GDP2006" > (SELECT MAX("GDP2005") FROM countries)<\/PRE>Voor file geodatabases kunnen de setfuncties AVG, COUNT, MIN, MAX en SUM alleen worden gebruikt binnen scalaire subqueries.<\/SPAN><\/P>EXISTS-predicate. Bijvoorbeeld:<\/LI><\/UL>EXISTS (SELECT * FROM indep_countries WHERE "COUNTRY_NAME" = 'Mexico')<\/PRE><\/BLOCKQUOTE><\/P>De documentatie vermeldt "beperkte ondersteuning" voor subqueries, maar vermeldt ook dat de EXISTS-predicate wordt ondersteund. Als subqueries niet het probleem zijn, zijn misschien gecorreleerde subqueries het probleem. Immers, geen van de EXISTS-voorbeelden in alle documentatie gebruikt een gecorreleerde subquery. Helaas blijft raden wat we overhouden omdat gecorreleerde subqueries niet expliciet worden genoemd in enige file geodatabase-documentatie die ik kan vinden.<\/P><\/P>Uit dit eenvoudige voorbeeld blijkt duidelijk dat de file geodatabase onjuiste resultaten geeft bij gebruik van EXISTS met gecorreleerde subqueries. Zijn de onjuiste resultaten een bug of beperking van SQL-ondersteuning in de file geodatabase? Zelfs als men probeert het laatste te beargumenteren, blijft het probleem dat de gebruiker onjuiste resultaten krijgt in plaats van een foutmelding, wat zou moeten zijn wat de gebruiker krijgt als gecorreleerde subqueries niet worden ondersteund.<\/P><\/BODY><\/HTML>
<\/P>
Een gebied waar gebruikers zichzelf in de problemen kunnen brengen met file geodatabases en SQL is de EXISTS-voorwaarde of operator. Als je kijkt naar de SQL Reference (FileGDB_SQL.htm) in de File Geodatabase API (
[NOT] EXISTS<\/P><\/TD>Geeft TRUE terug als de subquery ten minste één record retourneert, anders geeft het FALSE terug. Bijvoorbeeld, deze expressie geeft TRUE terug als het OBJECTID-veld een waarde van 50 bevat:<\/P>EXISTS (SELECT * FROM parcels WHERE "OBJECTID" = 50)<\/PRE>EXISTS wordt alleen ondersteund in file, personal en ArcSDE geodatabases.<\/TD><\/TR><\/TBODY><\/TABLE><\/BLOCKQUOTE><\/P>Aangezien SQL EXISTS wordt ondersteund in de file geodatabase, hoe kan iemand dan toch problemen krijgen bij het gebruik ervan? Helaas is het makkelijker dan je zou verwachten, en het antwoord ligt bij gecorreleerde subqueries.<\/P><\/P>Gecorreleerde subqueries zijn vrij gebruikelijk bij het werken met EXISTS, eigenlijk zo gebruikelijk dat Microsoft's
[NOT] EXISTS<\/P><\/TD>
Geeft TRUE terug als de subquery ten minste één record retourneert, anders geeft het FALSE terug. Bijvoorbeeld, deze expressie geeft TRUE terug als het OBJECTID-veld een waarde van 50 bevat:<\/P>
EXISTS (SELECT * FROM parcels WHERE "OBJECTID" = 50)<\/PRE>EXISTS wordt alleen ondersteund in file, personal en ArcSDE geodatabases.<\/TD><\/TR><\/TBODY><\/TABLE><\/BLOCKQUOTE><\/P>Aangezien SQL EXISTS wordt ondersteund in de file geodatabase, hoe kan iemand dan toch problemen krijgen bij het gebruik ervan? Helaas is het makkelijker dan je zou verwachten, en het antwoord ligt bij gecorreleerde subqueries.<\/P><\/P>Gecorreleerde subqueries zijn vrij gebruikelijk bij het werken met EXISTS, eigenlijk zo gebruikelijk dat Microsoft's
Het volgende voorbeeld is aangepast van
>><\/SPAN>><\/SPAN> fgdb =<\/SPAN> # pad naar file geodatabase<\/SPAN>\n>><\/SPAN>><\/SPAN> pgdb =<\/SPAN> # pad naar personal geodatabase<\/SPAN>\n>><\/SPAN>><\/SPAN> egdb =<\/SPAN> # pad naar enterprise geodatabase, SQL Server gebruikt in voorbeeld<\/SPAN>\n>><\/SPAN>><\/SPAN> gpkg =<\/SPAN> # pad naar GeoPackage<\/SPAN>\n>><\/SPAN>><\/SPAN> gdbs =<\/SPAN> (<\/SPAN>fgdb, pgdb, egdb, gpkg)<\/SPAN>\n>><\/SPAN>><\/SPAN> \n>><\/SPAN>><\/SPAN> values =<\/SPAN> (<\/SPAN>(<\/SPAN>"A"<\/SPAN>, 1<\/SPAN>)<\/SPAN>, )<\/SPAN>:<\/SPAN>.<\/SPAN>.<\/SPAN>.<\/SPAN> table =<\/SPAN> arcpy.<\/SPAN>CreateTable_management(<\/SPAN>gdb, <\/SPAN>table_names[<\/SPAN>i-1<\/SPAN>]<\/SPAN>)<\/SPAN>.<\/SPAN>.<\/SPAN>.<\/SPAN> arcpy.<\/SPAN>AddField_management(<\/SPAN>table, <\/SPAN>"id"<\/SPAN>, <\/SPAN>"TEXT"<\/SPAN>)<\/SPAN>.<\/SPAN>.<\/SPAN>.<\/SPAN> arcpy.<\/SPAN>AddField_management(<\/SPAN>table, <\/SPAN>"version"<\/SPAN>, <\/SPAN>"LONG"<\/SPAN>)<\/SPAN> .<\/SPAN>.<\/span>.<\/span> with<\/span> arcpy. < / Span > da < Span Class = "Punctuation Token ">. < / Span > InsertCursor < Span Class = "Punctuation Token ">( < / Span > table < Span Class = "Punctuation Token ">, < / Span > ( < Span Class = "String Token "> "id" < / Span > , < Span Class = "String Token "> "version" < / Span > ) < Span Class = "Punctuation Token ">) < / Span > < span Class = "Keyword Token ">as< / span > cur < span Class = "Punctuation Token ">: < / span >. < / span > < span Class = "Punctuation Token ">. < / span > < span Class = "Punctuation Token ">. < / span >& nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; cur.insertRow(value). < / span > < span Class = "Punctuation Token ">. < / span > < span Class = "Punctuation Token ">. < / span >& nbsp ; & nbsp ; & nbsp ; & nbsp ;. < / span > < span Class = "Punctuation Token ">. < / span > < span Class = "Punctuation Token ">. < / span >& nbsp ; & nbsp ; & nbsp ; & nbsp ; qry = ( < span Class = "String Token "> "BESTAAT (SELECT 1" . . . & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; " VAN TableB". . . & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; & nbsp ; " WAAR TableB.id = TableA.id". . . & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp; & nb sp;Opmerking:<\/H5>Coverages, shapefiles en andere niet-geodatabase op bestanden gebaseerde gegevensbronnen ondersteunen geen subqueries. Subqueries die worden uitgevoerd op versioned ArcSDE feature classes en tabellen zullen geen features retourneren die zijn opgeslagen in de delta-tabellen. File geodatabases bieden de beperkte ondersteuning voor subqueries die in deze sectie wordt uitgelegd, terwijl personal en ArcSDE geodatabases volledige ondersteuning bieden. Voor informatie over de volledige set subquery-mogelijkheden van personal en ArcSDE geodatabases, raadpleeg uw DBMS-documentatie.<\/P><\/DIV><\/P><\/P><\/P><\/P>Een subquery is een query genest binnen een andere query. Het kan worden gebruikt om predicate- of aggregatiefuncties toe te passen of om gegevens te vergelijken met waarden die in een andere tabel zijn opgeslagen....<\/P><\/BLOCKQUOTE><\/P>Subquery-ondersteuning in file geodatabases is beperkt tot het volgende:<\/P>IN-predicate. Bijvoorbeeld:<\/LI><\/UL>"COUNTRY_NAME" NOT IN (SELECT "COUNTRY_NAME" FROM indep_countries)<\/PRE>Scalaire subqueries met vergelijkingsoperatoren. Een scalaire subquery retourneert een enkele waarde. Bijvoorbeeld:<\/LI><\/UL>"GDP2006" > (SELECT MAX("GDP2005") FROM countries)<\/PRE>Voor file geodatabases kunnen de setfuncties AVG, COUNT, MIN, MAX en SUM alleen worden gebruikt binnen scalaire subqueries.<\/SPAN><\/P>EXISTS-predicate. Bijvoorbeeld:<\/LI><\/UL>EXISTS (SELECT * FROM indep_countries WHERE "COUNTRY_NAME" = 'Mexico')<\/PRE><\/BLOCKQUOTE><\/P>De documentatie vermeldt "beperkte ondersteuning" voor subqueries, maar vermeldt ook dat de EXISTS-predicate wordt ondersteund. Als subqueries niet het probleem zijn, zijn misschien gecorreleerde subqueries het probleem. Immers, geen van de EXISTS-voorbeelden in alle documentatie gebruikt een gecorreleerde subquery. Helaas blijft raden wat we overhouden omdat gecorreleerde subqueries niet expliciet worden genoemd in enige file geodatabase-documentatie die ik kan vinden.<\/P><\/P>Uit dit eenvoudige voorbeeld blijkt duidelijk dat de file geodatabase onjuiste resultaten geeft bij gebruik van EXISTS met gecorreleerde subqueries. Zijn de onjuiste resultaten een bug of beperking van SQL-ondersteuning in de file geodatabase? Zelfs als men probeert het laatste te beargumenteren, blijft het probleem dat de gebruiker onjuiste resultaten krijgt in plaats van een foutmelding, wat zou moeten zijn wat de gebruiker krijgt als gecorreleerde subqueries niet worden ondersteund.<\/P><\/BODY><\/HTML>
File Geodatabase does not support correlated subqueries,
After publishing the blog post, I got to wondering how GeoPackages are handled. It turns out, they work just fine, i.e., one can create the tables and table view from a GeoPackage and get the correct results. I went ahead and updated the code to include using a GeoPackage.
lshipman-esristaff, thanks for the inside scoop. Do you have any idea if that recognition of response differences in geodatabases means that the documentation will be updated to be a bit more explicit, that there will be fixes (next version, patches, hotfixes) to allow SQL Correlated Subqueries to work in fGDB like they work in other data formats in the future, or is it just that this as far as it goes for the time? Thanks in advance.
I plan on updating the documentation Post 10.5. Support of SQL Correlated Subqueries is not currently planned for the fGDB, but if a persuasive business case is submitted we will consider it.
Although my blog post example involved two tables, one of our most common uses for correlated subqueries is actually self-correlated subqueries:
<SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> fgdb <SPAN class="operator token">=</SPAN> <SPAN class="comment token"># path to file geodatabase</SPAN> <SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> pgdb <SPAN class="operator token">=</SPAN> <SPAN class="comment token"># path to personal geodatabase</SPAN> <SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> egdb <SPAN class="operator token">=</SPAN> <SPAN class="comment token"># path to enterprise geodatabase, SQL Server used in example</SPAN> <SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> gpkg <SPAN class="operator token">=</SPAN> <SPAN class="comment token"># path to GeoPackage</SPAN> <SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> gdbs <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN>fgdb<SPAN class="punctuation token">,</SPAN> pgdb<SPAN class="punctuation token">,</SPAN> egdb<SPAN class="punctuation token">,</SPAN> gpkg<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> <SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> values <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">"A"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">1</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">"A"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">2</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">"B"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">1</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">"B"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">2</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">"C"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">2</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">"C"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">3</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">"D"</SPAN><SPAN class="punctuation token">,</SPAN> None<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">"E"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">1</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> <SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> table_name <SPAN class="operator token">=</SPAN> <SPAN class="string token">"TableA"</SPAN> <SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> <SPAN class="operator token">>></SPAN><SPAN class="operator token">></SPAN> <SPAN class="keyword token">for</SPAN> gdb <SPAN class="keyword token">in</SPAN> gdbs<SPAN class="punctuation token">:</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> table <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>CreateTable_management<SPAN class="punctuation token">(</SPAN>gdb<SPAN class="punctuation token">,</SPAN> table_name<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>AddField_management<SPAN class="punctuation token">(</SPAN>table<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"id"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"TEXT"</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>AddField_management<SPAN class="punctuation token">(</SPAN>table<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"version"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"LONG"</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> <SPAN class="keyword token">with</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>InsertCursor<SPAN class="punctuation token">(</SPAN>table<SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">"id"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"version"</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">as</SPAN> cur<SPAN class="punctuation token">:</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> <SPAN class="keyword token">for</SPAN> value <SPAN class="keyword token">in</SPAN> values<SPAN class="punctuation token">:</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> cur<SPAN class="punctuation token">.</SPAN>insertRow<SPAN class="punctuation token">(</SPAN>value<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> qry <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">"NOT EXISTS (SELECT 1"</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> <SPAN class="string token">" FROM TableA a"</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> <SPAN class="string token">" WHERE TableA.id = a.id"</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> <SPAN class="string token">" AND TableA.version < a.version)"</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> table_view <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>MakeTableView_management<SPAN class="punctuation token">(</SPAN>table<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"table_view"</SPAN><SPAN class="punctuation token">,</SPAN> qry<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>TableToTable_conversion<SPAN class="punctuation token">(</SPAN>table_view<SPAN class="punctuation token">,</SPAN> gdb<SPAN class="punctuation token">,</SPAN> table_name <SPAN class="operator token">+</SPAN> <SPAN class="string token">"_max"</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> <SPAN class="keyword token">print</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>GetCount_management<SPAN class="punctuation token">(</SPAN>table_view<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="punctuation token">.</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Delete_management<SPAN class="punctuation token">(</SPAN>table_view<SPAN class="punctuation token">)</SPAN> <SPAN class="number token">8</SPAN> <SPAN class="number token">5</SPAN> <SPAN class="number token">5</SPAN> <SPAN class="number token">5</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
The use of a self-correlated subquery allows for selecting the maximum or minimum record for a given attribute. In the example above, a self-correlated subquery is used to select the record with the maximum value of version for each value of id.
@LanceShipman
Regarding:
"File Geodatabase does not support correlated subqueries"
Does that still apply to ArcGIS Pro 3.0.3? There seems to be a lot of stuff supported in FGDBs these days, including INNER JOIN (SQL for reporting and analysis on file geodatabases) and database views. I'd like to think correlated subqueries would be supported in this modern age.
I ask because of a related post I wrote here: File Geodatabase SQL expression to get greatest n per group
Related ideas:
BUG-000156143 - An SQL query containing the EXISTS predicate validates successfully but returns incorrect results from a file geodatabase.ENH-000156158 - Raise exception when using unsupported SQL expressions in file geodatabases.
Esri Canada Case 03264937 - Exception not raised when unsupported FGDB SQL used (correlated subquery)
10-25-2016 12:35 PMI plan on updating the documentation Post 10.5. Support of SQL Correlated Subqueries is not currently planned for the fGDB, but if a persuasive business case is submitted we will consider it.
10-25-2016 12:35 PM
I would say the "greatest 1 per group" scenario is a worthwhile business case for supporting correlated subqueries in file geodatabases. Currently, there doesn't seem to be a way to do that in FGDB SQL expressions.
It's a common requirement. For example: Selecting the most recent records based on unique values in another field
Aangemelde leden kunnen berichten plaatsen, updates volgen en meer. Nieuw hier? Registreer een gratis account.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.