I created this query:
SELECT
(SELECT value from UNNEST(project.labels) where key = "project") as project,
ROUND(SUM(cost), 2) as cost
FROM cloud.dataset.billing_export
group by ar
And it returns me something like:
Row | project | cost
1 | PJ1 | 23
2 | PJ2 | 50
Is there a way to create a VIEW for each value (each project)?
I'm trying with UDF and each view must have a name based on the project (eg: view_PJ1) and got something like (but with a lot of errors):
LOOP
SET vars = (SELECT (SELECT value FROM UNNEST(project.labels) WHERE key = "project") AS project
FROM FROM cloud.dataset.billing_export
GROUP BY project);
IF vars=null THEN
LEAVE;
END IF;
CREATE OR REPLACE VIEW `cloud`.`dataset`.AR
AS
SELECT DISTINCT
(SELECT value from UNNEST(project.labels) where key = "project") as project,
ROUND(SUM(cost), 2) as cost
FROM cloud.dataset.billing_export
WHERE project=vars
GROUP BY project;
END LOOP;
Thanks in advance
This is a script that runs inside BigQuery that generates 4 views - giving each view a name coming out of a SQL query:
DECLARE x INT64 DEFAULT 0;
DECLARE rs ARRAY<STRING>;
SET rs = (
WITH data AS (SELECT i FROM `fh-bigquery.public_dump.numbers_255` WHERE i < 4)
SELECT ARRAY_AGG(
'CREATE OR REPLACE VIEW `temp.number' || i
||'` AS SELECT i FROM `fh-bigquery.public_dump.numbers_255` WHERE i=' || i
)
FROM data
);
LOOP
EXECUTE IMMEDIATE(SELECT rs[OFFSET(x)]);
SET x = x + 1;
IF x >= ARRAY_LENGTH(rs) THEN
LEAVE;
END IF;
END LOOP;
The secret is to use EXECUTE IMMEDIATE with a generated string creating the view.
Related
I am facing for me strange issue with following parametrical cursor.
I have defined cursor in this way:
CURSOR cur_action ( product_code VARCHAR2(100) , action_master_list VARCHAR2(100))
IS
SELECT
act.ACTION_DETAIL_KEY,
act.ACTION_MASTER_KEY,
act.PRODUCT_CODE,
act.REF_ACTION_DETAIL_KEY
FROM XMLTABLE(action_master_list) x
JOIN ETDW.MFE_AR_ACTION_DETAILS act ON TO_NUMBER(x.COLUMN_VALUE) = act.ACTION_MASTER_KEY
WHERE 1=1
AND act.LAST_FLAG = 'Y'
AND act.PRODUCT_CODE = product_code;
Then I am using it in following way:
OPEN cur_action ( iFromProductCode , iActionMasterKeyList);
LOOP
FETCH cur_action BULK COLLECT INTO vActionDetailKey, vActionMasterKey, vProductCode, vRefActionDetailKey LIMIT 100;
FOR j IN 1..cur_action%ROWCOUNT
LOOP
dbms_output.put_line('vActionDetailKey: ' || vActionDetailKey (j) ||' vActionMasterKey: '|| vActionMasterKey (j) || ' vProductCode: ' || vProductCode (j));
END LOOP;
END LOOP;
Result seems to be unfilterd. It doesnt return 3 rows as expected result (this result is returned in with cusor query, when i run in outside procedure/pl block), but it returns all rows for actions in list. So it seems, that WHERE condition "act.PRODUCT_CODE = product_code" was not applied. Why?
Thank you
Why? Because you named parameter the same as column, so Oracle reads it as if it was where 1 = 1, i.e. no filtering at all.
Rename parameters to e.g.
CURSOR cur_action ( par_product_code V
----
this
and, later,
AND act.PRODUCT_CODE = par_product_code;
----
this
is it possible, in postgresql - to access a cte defined in a view?
By that I mean - if you have the following:
create view my_view as
with
blah as (select 1 as x, 2 as y, 3 as z)
select
x*x as x_squared,
y*y as y_squared,
z*z as z_squared
from
blah
is there any way from outside of getting at blah? eg looking for something like:
select * from my_view.blah
Basically we have large views that use a number of complicated CTE's - and it's quite difficult sometimes to troubleshoot them without splitting them all out into separate smaller views [yes, I would prefer to just keep it like that, but I don't have that option]
I know I will be able to do it by making a stored proc that pulls out the view definition - extracts the with clauses, parses up to the blah definition, changes that to the main select, gets rid of the rest, and then does the query - but that all seems like a lot of work. Am hoping there's a built-in way?
You can create the CTE as a view by itself. For example:
create table a (b int);
insert into a (b) values (1), (50), (200), (350), (1000);
create view blah as
select * from a where b > 100;
Anf then base your original view on this new intermediate one to avoid repeating code:
create view my_view as
select * from blah where b < 500;
See running example at DB Fiddle.
ok - so I have a sort of solution - it's a not a function - it's a procedure that turns a cte into a materialized_view.
I first wanted to formulate it as function, so you could say:
select * from cte_from( 'my_real_view', 'the_cte' )
but it appears that a function needs its schema defined in advance, which is obviously impossible in this case. If anyone can suggest a hack to make it closer to above, I'd apperciate it. But anyway - bottom line this works:
create procedure from_cte(view_schema text, view_name text, cte_name text, materialized_view_name text) as
$func$
declare
_code text;
_others text;
_script text;
begin
execute format('drop materialized view if exists %s', materialized_view_name);
with recursive
string_provider as (
select view_definition as the_string,
position(concat(cte_name, ' as (') in lower(view_definition)) + length(cte_name) + 5 as start_location
from information_schema.views
where table_name = view_name
and table_schema = view_schema
),
string_walk as (
select start_location as x,
1 as brackets
from string_provider
union
select x + 1,
new_brackets
from string_provider,
string_walk,
lateral (select case
when substring(the_string from x + 1 for 1) = '(' then brackets + 1
when substring(the_string from x + 1 for 1) = ')' then brackets - 1
else brackets
end as new_brackets
) calculated
where new_brackets != 0
and x < length(the_string)
)
select substring(the_string from start_location for 1 + max(x) - start_location),
trim(substring(the_string from 0 for start_location - length(cte_name) - 5))
into _code, _others
from string_walk,
string_provider
group by the_string, start_location;
if length(_others) < 5 then
select _code into _script;
else
select concat(substring(_others from 0 for length(_others)), ' ', _script) into _script;
end if;
execute format('create materialized view %s as ( %s )', materialized_view_name, _code);
end
$func$ language plpgsql;
I am trying to get the location of the last time an item was moved via sql function with the code below. Pretty basic, I'm just trying to grab the max date and time. If I run the sql as a regular select and hard code an item number in ATPRIM I get only one location. But if I create this function and then try to run it and then pass the function an item number I get every occurrence in the history file instead of just the MAX which would be the most recent. Also I have tried a Select Distinct and that did not do anything for me.
ATOGST = Item Location
ATPRIM = Item
ATDATE = Date
ATTIME = Time
CREATE FUNCTION ERPLXU/F#QAT1(AATPRIM VARCHAR(10))
RETURNS CHAR(50)
LANGUAGE SQL
NOT DETERMINISTIC
BEGIN DECLARE F#QAT1 CHAR(50) ;
SET F#QAT1 = ' ' ;
SELECT ATOGST
INTO F#QAT1 FROM ERPLXF/QAT as t1
WHERE ATPRIM = AATPRIM
AND ATDATE = (SELECT MAX(ATDATE) FROM ERPLXF/QAT AS T2
WHERE T2.ATPRIM = AATPRIM)
AND ATTIME = (SELECT MAX(ATTIME) FROM ERPLXF/QAT AS T3
WHERE T3.ATPRIM = AATPRIM
AND T3.ATDATE = T1.ATDATE) ;
RETURN F#QAT1 ;
END
EDIT:
So what I am trying to do is get that location and I got it to work on my iSeries in strsql but the problem is we use a web application called Web Object Wizard (WoW) which lets us use sql to make reports that are more user friendly. Below is what I was trying to get to work but the subquery in the select does not work in WoW so that is where I was trying create a function which we know works in other applications.
SELECT distinct t1.atprim, atdesc, dbtabl, dbdtin, dblife, dblpdp,
dbcost, dbbas, dbresv, dbyrdp, dbcurr,
(select atogst
from erplxf.qat as t2
where t1.atprim = t2.atprim and atdate = (select max(atdate) from
erplxf.qat as t3 where t2.atprim = t3.atprim) and attime = (select
max(attime) from erplxf.qat as t4 where t1.atprim = t4.atprim and
t1.atdate = t4.atdate)
) as #113_ToLoc
FROM erplxf.qat as t1 join erplxf.qdb on atassn = dbassn
where dbrcid = 'DB'
and dbcurr != 0
So instead of that subquery at the end of the select it would just be
, erplxu.f#qat1(atprim) as #113_ToLoc
Try this:
CREATE FUNCTION ERPLXU/F#QAT1(AATPRIM VARCHAR(10))
RETURNS CHAR(50)
LANGUAGE SQL
RETURN
SELECT ATOGST
FROM ERPLXF/QAT
WHERE ATPRIM = AATPRIM
ORDER BY ATDATE DESC, ATTIME DESC
FETCH FIRST 1 ROW ONLY;
In my database I have a table "Datapoint" with the two columns "Id" (integer) and "Description" (character varying). Table "Datapoint"
I then have a table "Logging" with the three columns "Id" (integer), "Dt" (timestamp without timezone) and "Value" (double precision).Table "Logging"
I also have the following function:
CREATE OR REPLACE FUNCTION count_estimate(query text)
RETURNS integer AS
$BODY$ DECLARE rec record;ROWS INTEGER;BEGIN FOR rec IN EXECUTE 'EXPLAIN ' || query LOOP ROWS := SUBSTRING(rec."QUERY PLAN" FROM ' rows=([[:digit:]]+)');EXIT WHEN ROWS IS NOT NULL;END LOOP;RETURN ROWS;END $BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
This function returns the estimated count of entries that are found by a SELECT-Query, e.g. SELECT count_estimate('SELECT * FROM "Logging" WHERE "Id" = 3') would return 2.
I would now like to combine a SELECT-query on the table "Datapoint" with the return value of my function, so that my result looks like this:
ID | Description | EstimatedCount
1 | Datapoint 1 | 3
2 | Datapoint 2 | 4
3 | Datapoint 3 | 2
4 | Datapoint 4 | 1
My SELECT-query should look something like this:
SELECT
"Datapoint"."Id",
"Datapoint"."Description",
(SELECT count_estimate ('SELECT * FROM "Logging" WHERE "Logging"."Id" = "Datapoint"."Id"')) AS "EstimatedCount"
FROM
"Datapoint"
So my problem is to write a functioning SELECT-query for my purposes.
What about:
SELECT
"Datapoint"."Id",
"Datapoint"."Description",
count_estimate ('SELECT * FROM "Logging" WHERE "Logging"."Id" = "Datapoint"."Id"') AS "EstimatedCount"
FROM
"Datapoint"
You almost got it right, except that you need to supply the value of "Datapoint"."Id":
SELECT
"Datapoint"."Id",
"Datapoint"."Description",
count_estimate(
'SELECT * FROM "Logging" WHERE "Logging"."Id" = ' || "Datapoint"."Id"
) AS "EstimatedCount"
FROM "Datapoint";
I have some codes.
I think this codes are related with dump files(.dmp).
I can not analyse this code.
I want to know what this code means.
Especially, about METRICEU.
METRICSUsynonyms
METRICEU 0
METRICSUviews
CREATE VIEW "VW_OPERRIGHT" ("VCID","OPERATORID","FUNCTIONID") AS
?select vcid,operatorid,functionid from cc_operright
union
select distinct a.vcid,a.operatorid,b.functionid from cc_operrole
a,cc_roleright b where a.roleid=b.roleid
CREATE VIEW "VW_AGENTRESTDETAIL" ("VCID","AGENTID","OPERNAME","AGENTPHONE","GROUPID","CLUSTERID","GROUPNAME"," APPLYTIME","CANCELTIME","AGREETIME","AUDITORNAME","AUDITORID","LEAVESTARTTIME","LEAVEENDTIME","LEAVETIMELEN","AGREELEN","APPLYRESULT","RESTMODE") AS select ard.vcid, ard.agentid,op.opername, ard.agentphone,
... ...
METRICEU 2
METRICSUstored procedures
ALTER SESSION SET "_LOAD_WITHOUT_COMPILE" = PLSQL
ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL = 2 NLS_LENGTH_SEMANTICS = 'BYTE' PLSQL_CODE_TYPE = 'INTERPRETED' PLSQL_DEBUG = TRUE PLSQL_WARNINGS = 'DISABLE:ALL'PLSQL_CCFLAGS = ''
CREATE FORMAT71 PROCEDURE "PR_JUDGERIGHT"
? CREATE procedure pr_judgeright(
+ apprvcid integer,
+ approperid integer,
+ checkedvcid integer,
) checkedoperid integer,
9 retflag out integer,
* retmsg out varchar2,
1 url out varchar2
) is v_count integer;
... ...
TABLE "NGCC_RECORD_WAY"
ANALCOMPUTE TS "NGCC_RECORD_WAY" ANALYZE TABLE "NGCC_RECORD_WAY" ESTIMATE STATISTICS
TABLE "RECTEMPLATE"
ANALCOMPUTE TS "RECTEMPLATE" ANALYZE TABLE "RECTEMPLATE" ESTIMATE STATISTICS
TABLE "TBL_114CALL"
ANALCOMPUTE TS "TBL_114CALL" ANALYZE TABLE "TBL_114CALL" ESTIMATE STATISTICS
TABLE "TBL_114CALL_BAK"
ANALCOMPUTE TS "TBL_114CALL_BAK" ANALYZE TABLE "TBL_114CALL_BAK" ESTIMATE STATISTICS
ENDTABLE
METRICEU 287
METRICEUG0
EXIT
EXIT