Your solution is perfect. I merely wanted to highlight one of the benefits of the new spatial aggregates we added back in v2019.
Original Message:
Sent: 06-25-2024 20:27
From: James Nolet
Subject: Where expression for Delete statements
I also forgot to mention that Peter will have a better solution!
Thanks Peter - I'll make sure I give the AggregateCombine function a go myself.
------------------------------
James Nolet
GIS Manager
Caf Consulting
Mentone office, VIC, Australia
Original Message:
Sent: 06-25-2024 04:42
From: Peter Møller
Subject: Where expression for Delete statements
You could speed up the subselect query by using the spatial aggregate AggregateCombine to combine the objects before comparing:
Select * From City_STREETS
Where obj within (Select AggregateCombine(obj) From Cities Where Cities.City like "City ,County")
This will only return one object to compare against.
------------------------------
Peter Horsbøll Møller
Principal Presales Consultant | Distinguished Engineer
Precisely | Trust in Data
Original Message:
Sent: 06-24-2024 11:16
From: James Nolet
Subject: Where expression for Delete statements
In addition to the above, I forgot to mention that the sub-select method:
Select * From City_STREETS Where obj within any (Select obj From Cities Where Cities.City like "City ,County")
can be a lot slower to execute where you have a lot of data. The alternative join/update method that I provided as a four-step process in my above reply can help in those situations.
------------------------------
James Nolet
GIS Manager
Caf Consulting
Mentone office, VIC, Australia
Original Message:
Sent: 06-23-2024 20:58
From: James Nolet
Subject: Where expression for Delete statements
Hi Derrick,
First, I think you have a typo in your post for the first Delete statement: the correct syntax is "Delete from selection". However, that won't work in your case because your select statement will produce a view of two joined tables. Changing your select statement to the following might give you the results you are after:
If wanting to delete from the City_STREETS table:
Select * From City_STREETS Where obj within any (Select obj From Cities Where Cities.City like "City ,County")
If wanting to delete from the Cities table:
Select * From Cities Where Cities.City like "City ,County" And obj contains any (Select obj From City_STREETS)
Then use the Delete statement.
I like to create a named query from which to delete. If taking this approach, the statements become:
Select * From City_STREETS Where obj within any (Select obj From Cities Where Cities.City like "City ,County") Into City_STREETS_sel
Delete From City_STREETS_sel
Because you are using a join, the enhanced Delete statement as described in Peter's article above will not work. You will need to use the two steps: Select the records, then Delete.
Another way of doing this is to:
- Join the tables together as you originally attempted (e.g. into a named query called "City_STREETS_join")
- Update a field in the results (e.g. Update City_STREETS_join Set Matched="Y")
- Select all Matched records from the base table: Select * From City_STREETS Where Matched="Y" Into City_STREETS_sel
- Delete: Delete From City_STREETS_sel
Another item to address in your query is the following clause:
Cities.City like "City ,County"
Do you mean to select records where Cities.City contains either "City" or "County"? Then use: Cities.City In ("City", "County")
Do you want to select records where Cities.City contains either "City" or "Count"? Then use: Cities.City Like "%City%" Or Cities.City Like "%County%"
Or perhaps you want to select records where Cities.City is exactly "City ,County", in which case the "like" keyword will work but is unnecessary; you could use: Cities.City = "City ,County"
Hopefully this helps a little.
------------------------------
James Nolet
GIS Manager
Caf Consulting
Mentone office, VIC, Australia
Original Message:
Sent: 06-21-2024 12:05
From: Derrick Race
Subject: Where expression for Delete statements
I don't know if there is a better place to post (since this post is 4 years old) but I can't find any other forum post that talks about this topic so here it is...How do I get around the inability to directly delete based off a selection made? It keeps giving me a "Cannot Delete from a view" message for the following script:
Select * from City_STREETS, Cities where Cities.obj contains City_STREETS.obj and Cities.City like "City ,County"
Delete * from selection
The select statement works as intended, but it won't allow for the Delete to take place. Replacing "Select *" with "Delete" ends up deleting all the data from my table, not just the data specified from the where clause
e.g. Delete from City_STREETS, Cities where Cities.obj contains City_STREETS.obj and Cities.City like "City ,County"
edit: I should also note that I am currently using MapInfo Pro 2021 Build 172
------------------------------
Derrick Race
Database Coordinator
DIGLINE INCORPORATED
BOISE ID
Original Message:
Sent: 01-15-2020 21:03
From: Peter Møller
Subject: Where expression for Delete statements
Over the coming weeks, I'll write a #series of articles about the SQL improvements we have made in MapInfo Pro v2019. This will, of course, look at the Select statement but I'll also dive into the other improvements.
This post will look at the improvement to the Delete Statement
Where expression for Delete statements
Just like the Update statement, the Delete statement has only supported a very limited Where condition; You could only specify a ROWID of the record that should be deleted
Delete From SomeTable Where ROWID = 1
This has, however, been very useful when writing MapBasic applications where you loop through a table and need to delete individual records.
With MapInfo Pro v2019, we have finally added support for a more complex Where condition for the Delete statement. The new syntax looks like this:
Delete [ Object ] From table
[ Where [RowId = id_number] | where_expr]
[ DropIndex ( Auto | On | Off ) ]
Earlier you would have to query out the records that you wanted to delete and then delete the records of this query:
Select * From SomeTable
Where Not OBJ
Into __TO__DELETE NoSelect
Delete From __TO__DELETE
Close Table __TO__DELETE
With MapInfo Pro v2019, you can do this in a single statement:
Delete From SomeTable
Where Not OBJ
You can use this statement when writing MapBasic applications, via the MapBasic Window and via the new SQL Window.
We don't have a dedicated dialog that helps you query out and delete specific records. Users will most either manually select the records and then hit the Delete key to delete the records or they would run a query to select the records they want to delete and they hit the Delete key.
This also means that this change will mean more to the MapBasic developers. However, as you saw above, the new SQL Window now lets users run their delete statements too.
A few more examples of possible Delete statements:
Deleting records with X and Y values of 0
Delete From SomeTable
Where X <> 0 And Y <> 0
Deleting records that don't have a spatial object
Delete From SomeTable
Where Not OBJ
Deleting records from a table of polygons where the polygon has less than 3 nodes
Delete From SomeTable
Where Val(Str$(ObjectInfo(OBJ, OBJ_INFO_NPNTS))) < 3
Do you find this improvement useful? How will you take advantage of it?
Stay tuned for more details on the improvements to the SQL language of MapInfo Pro v2019!
------------------------------
Peter Horsbøll Møller
Distinguished Engineer
Pitney Bowes Software & Data
------------------------------