The key thing is that an ORDER BY in a materialized view makes no sense.
Under the covers, a materialized view is really just a table that gets automatically updated when the tables it is based on get updated. But being a table means that no ordering can ever be guaranteed. Even though the initial MV gets stored in the desired order, there is no guarantee it will remain so after updates are applied. The only way to make sure you get the results in the proper order is to use an explicit ORDER BY when you select from the MV.
You can include an ORDER BY into a view (not a materialized view), and that will be applied when you do use that view: selects from the view then do not need any ORDER BY. But this is a VERY BAD practice. It means that applications may unknowingly depend on some assumed order provided by a view - until someone decides to remove the ORDER BY from the view and all hell breaks loose.
The key is: if an application requires a result in a specific order, then it must say so in the SELECTs it issues, by including an ORDER BY.
That said, looking at your MV definition, it looks like it will never be updated as changes take place on the base tables (PLACES and COORDINATES): you say that it is "REFRESH ON DEMAND COMPLETE". In other words you (or some automatic process) triggers a full refresh at regular intervals. This is exactly the same as creating a new table. You might as well do this:
CREATE TABLE PlaceCoordinates AS
SELECT Places.ID, Coordinates.Point
FROM Places
LEFT OUTER JOIN Coordinates ON Places.ID = Coordinates.ID;
and run this every time you want to refresh your PLACECOORDINATES table (after dropping the old table). It will be simpler and more efficient than the MV machinery. Another approach is to create the table once, then truncate and fill it when necessary:
CREATE TABLE PlaceCoordinates (
ID NUMBER PRIMARY KEY,
Point SDO_GEOMETRY
);
and
TRUNCATE TABLE PlaceCoordinates;
INSERT INTO PlaceCoordinates (ID, Point)
SELECT Places.ID, Coordinates.Point
FROM Places
LEFT OUTER JOIN Coordinates ON Places.ID = Coordinates.ID;
That lets you specify that ID is a primary key - always a good idea. And of course, don't forget to define the proper spatial index on the POINT column (assuming you want to show the points on a map or query them). Good practice then is to first drop that index before you refresh the content and recreate it afterwards (you need that also for the MV approach).
Whatever the chosen approach (MV as you specify it, or table), PLACECOORDINATES will not reflect the real-time state of the PLACES and COORDINATES tables. It will only reflect the state at the last time you manually fully refreshed the MV or re-loaded the table. If this is acceptable, then you are all set.
If you want that PLACECOORDINATES is closer to the state of the other two tables, without having to fully refresh/reload it, say every minute, then you need to define the MV so it is refreshed only from the changes in the source tables. That means that you need a MATERIALIZED VIEW LOG on those tables where changes will be recorded in order to be applied on the MV. That however will only happen at the intervals you specify or you when manually request a refresh. But reasonably not more than every minute. Certainly not every second.
If PLACECOORDINATES must reflect all changes in PLACES and COORDINATES as they happen (= in "real time"), then the only way to guarantee that is to make it a table and have triggers on PLACES and COORDINATES automatically apply changes on those tables on PLACECOORDINATES as they happen.
Maybe in that case you are better off just reading directly from the base tables.
order by 1
you're still referencingplaces.ID
, just by position. Does it let youorder by ID
without the table prefix? – Sanctimoniousorder by
when you query the MV - which wouldn't be guaranteed to work? – SanctimoniousPlaces.ID
? I will test without table prefix when I get back to work tomorrow. – GlasscoID
if the positional reference doesn't, but perhaps worth trying. Aside from those two docs I mentioned, no, I'm afraid not. – Sanctimoniousorder by
when querying the MV. I must admit that I did not know that it was not guarantedd to work, so I guess that means I no longer need to get this to work. Again, thank you for your help. – Glasscoorder by
when you query the MV, it might not one day. – Sanctimonious