I'd like call function within a view to resolve virtual column. Calculating depends on data in actual row and did not want to multiple times selecting a data. Is this correct?? And like bonus, is possible call function within a call another?
CREATE VIEW my_view AS SELECT c.column1,c.columns2,... my_function(c) FROM my_table c
CREATE VIEW my_view AS SELECT c.money, c.quantity,... my_ratio_function(c.money,c.quantity,select sum_all_pays(my_view)) FROM my_table c
note. I'm put here because when looked for, cannot find that. If you have any other ideas, put it. Second one command not sure if is correct.
It is fine to use functions in the view definition. The only constraint — you should always give an explicit name to the column that is actually a function call, otherwise PostgreSQL doesn't know how to present a view definition.
Still, you cannot reference the view from inside the view. Instead, you might create 2 views, then you can reference the inside one from the outside view. Another approach is to use the WITH construct, which I find very handy and do use a lot.
Please note, that view is just a server-stored SQL and functions will be called for each row each time you will be querying the view. To get some performance improvements you might want to define your functions either as IMMUTABLE or as STABLE.
And I do agree with Frank — go ahead and test your views.
Related
I am using PostgreSQL for GIS purposes with PostGIS and QGIS, but I think I might find more informations here than on gis.stackexchange.com since my question is not directly GIS related.
I am using views to diplay datas at will for the specific needs of my users, like that they have access to the datas as they are in the DB, but with just what they need. I added some rules to my views to make them "updatable" in QGIS and make them directly "workable" by the users.
Display in QGIS is based on attributes, but since there is the possibility that different persons will access the same data at the same moment, and they might want to display and hide some of these datas according to their needs (map printing for once). So I am looking for a way to give possibility to have a specific display for each view, and I thought about simply adding a "virtual" column in the view definition, with for example a boolean like such:
CREATE VIEW view1 AS
SELECT oid, column1, True as display from table1;
But I would like my users to be able to change the value of this column, to simply make appear or disappear the objects from the canvas (with a ruled-base styling considering this parameter). And obviously it doesn't work direclty since the update would be in conflict with the definition of the view.
Does anyone have any idea on how to achieve that? Maybe a materialized view (but I quite like the dynamics of the regular view)?
Thanks.
If the unique ID field is read from the table (i.e. it is not dynamically created via the row_number() trick commonly used with spatial views in QGIS), you could create a visibility manager table and use it in the view. You could have one table by view or one for all of them. Something similar to:
create table visibility_manager (oid bigint, visibility_status boolean, viewname text);
CREATE VIEW view1 AS
SELECT table1.oid, column1, coalesce(visibility_status,true) as display
from table1
left outer join visibility_manager
on (table1.oid = visibility_manager.oid and visibility_manager.viewname = 'view1');
see it in action:
http://rextester.com/OZPN1777
Good morning everyone!
I currently work with postgresql. Well, I need to create views where the numeric columns stay rounded 15.3 but I'm encountering a problem I could not understand.
The select work:
select cast(15.2547 as decimal(15,3)) as quantidade_medida_estatistica
The view not working:
create or replace view teste as select cast(15.2547 as decimal(15,3)) as quantidade_medida_estatistica
Error:
ERROR: can not change the data type of column view "quantidade_medida_estatistica" of numeric (15,4) to numeric (15,3)
Thanks!
This is a known "bug" in Postgres, which you can read about here.
CREATE OR REPLACE VIEW is not exactly the same as dropping the view and re-creating it. In this case the existing columns in the view need to be the same, as described in the documentation:
CREATE OR REPLACE VIEW is similar, but if a view of the same name
already exists, it is replaced. The new query must generate the same
columns that were generated by the existing view query (that is, the
same column names in the same order and with the same data types), but
it may add additional columns to the end of the list. The calculations
giving rise to the output columns may be completely different.
You can do what you want by dropping and re-creating the view.
You didn't explicitly state that, but I guess the view already exists - at least the error message indicates that.
Unfortunately you can't change the data types of the columns of an existing view when using create or replace.
You need to drop and create the view:
drop view teste;
create view teste
as
select cast(15.2547 as decimal(15,3)) as quantidade_medida_estatistica;
I have a table called transactions. Within that is a field called ipn_type. I would like to create separate table occurrences for the different ipn types I may have.
For example, one value for ipn_type is "dispute". In the past I would create a global field called "rel_dispute" and I would populate that with the value of "dispute". Then I could create a new table occurrence of the transactions table, and make a relationship based on transactions::ipn_type = transactions::rel_dispute. This way only the dispute records would show up in my new table occurrence.
Not long ago, somebody pointed out to me that this is no longer necessary, and there is a simpler way to setup such a relationship to create a new table occurrence. I can't for the life of me remember how that was done, though.
Any information on this would be greatly appreciated. Thanks!
To show a found set of only one type, you must either perform a find or use the Go to Related Record script step to show only related records. What you describe as your previous setup fits the latter.
The simpler way is to perform a find - either on demand, or by a script triggered OnLayoutEnter.
The new 'easy' way is probably:
using one base relationship only and
filtering only the displaying portal by type. This can be done with a global field, a global variable containing current display type. Multiple portals with different filter conditions are possible as well.
~jens
I would like to write a macro that works on the selected table.
Selection in a table
When I select a table, the object that ThisComponent.CurrentSelection returns is of type SwXTextTableCursor. I will refer to it generically as TextTableCursor.
According to DBG_methods it provides methods to traverse through the selected cells and merge or split the cells, but it doesn't seem to provide a way to access the actual table itself. Conversely, ThisComponent.TextTables returns the tables.
As far as I can tell, there is no way to determine if some cells or all of a table is selected.
Question
Is there any way to retrieve the TextTable(s) from TextTableCursor?
To get current selected TextTable use
ThisComponent.CurrentController.ViewCursor.TextTable
So I basicly have a table which has a list of table names. All these listed tables have exact same structure.
Then I have a query template, with place holder for table name.
I need to create a view, which should return results of that query UNIONed from all the tables listed in that one setup table.
So far what I've done is create a user defined function, which would prepare a complete UNIONed SQL statement.
But this is where I'm stuck. I can't figure out how to execute it in a view and return whatever it returns..
My function returns SQL syntax.
I figured that UDF can't executed dynamic sql, so my method won't work. So far I've solved my issue at hand by generating views. But I would still prefer a more dynamic way..