SQL Server 2000 with statement and recursive with - recursion

I have a problem in SQL Server 2000. I cannot send a recursive WITH query because CTE was introduced in SQL Server 2005.
My question is the following:
how can I retrieve the answer of a hierarchy if I do not want to use a procedure but I can send 2 queries in which case I can include the answer of the first query in the second.
This is the query for SQL Server 2005:
WITH recursive_back (SOACTION,SOACTIONS) AS
(SELECT child.SOACTION,child.SOACTIONS
FROM soaction child
WHERE child.soaction ={id to search}
UNION ALL
SELECT parent.SOACTION,parent.SOACTIONS
FROM recursive_back child,soaction parent
WHERE child.soactions = parent.soaction ),
recursive_ahead (SOACTION,SOACTIONS) AS
(SELECT parent.SOACTION, parent.SOACTIONS
FROM soaction parent,recursive_back
WHERE parent.soaction=recursive_back.soaction
UNION ALL
SELECT child.SOACTION, child.SOACTIONS
FROM recursive_ahead parent, soaction child
WHERE child.soactions = parent.soaction)
SELECT R.SOACTION,R.SOACTIONS
FROM recursive_back R, SOACTION A
WHERE R.SOACTION=A.SOACTION
UNION
SELECT R.SOACTION,R.SOACTIONS
FROM recursive_ahead R, SOACTION A
WHERE R.SOACTION=A.SOACTION;
GO

Related

Teradata, volatile table and nocount?

So I'm having some issues with a ETL-job where I'm trying to query out a statement including the creation of a volatile table (VT) with the adjoining insert.
Though I'm not sure I think I'm having an issue equivalent to MS-SQL temp table insert if you don't have the "SET NOCOUNT ON" -> I.e. the row count from the insert into the VT is returned to my to my cursor instead of the query using the VT.
I can't use a CTE (don't think I can) because I am inserting a pivoted result into the VT as I need to be able to reference the columns in the main select.
I can't create a view because this is a managed system for a banking core solution; with other words I have no right other than read from which I use to synthesize data from views and extract them.
For the same reason I can't create a stored procedure.
I've googled my way half around the world in 2,5 languages, but I'm not able to find any Teradata equivalent of "SET NOCOUNT ON".
I'm triggering the load from Azure Data Factory and I have a On Prem self hosted integration runtime to ensure connectivity to the TeradataDB.
Needless to say Teradata is not my strong suit and I'm hoping for some help from you guys :)
In advance! Many thanks!
Edit:
So here is the structure of the query:
Create volatile table StackOverflowTable
(
Key1(40),
Pivot1 float,
Pivot2 float,
Pivot3 float
)primary index (Key1) ON COMMIT PRESERVE ROWS;
;
insert into StackOverflowTable
select *
from
(
select atv.row1 Key1
, atv.row2
atv.row3
, row_number() over(partition by atv.row1 order by atv.row2 desc) RowNum
from aTeradataView atv
)s1
Pivot
(
sum(s1.row2) amt1,
sum(s1.row3) amt2
for RowNum in(1,2,3,4)
)p
;
with cte as
(
select av.row_av_1
, av.row_av_2
, av.row_av_3
, av.row_av_4
, av.ReportDate
from anotherView av
)
select cte.row_av_1
, cte.row_av_2
, cte.row_av_3
, cte.row_av_4
, sf.Pivot1
, sf.Pivot2
, sf.Pivot3
, cte.ReportDate StartLoadDate
, '9999-12-31' EndLoadDate
from cte
inner join StackOverflowTable sf on sf = cte.row_av_1
;
DROP TABLE StackOverflowTable
;

How to reuse a table with UNION?

I am trying to reuse a table in SQLite. My attempt is as follows:
SELECT
Partials.e_sentence
FROM
(SELECT
e_sentence, _id
FROM
Pair
JOIN PairCategories
ON
_id=PairId AND CategoryId=53
UNION
SELECT
e_sentence, _id
FROM
Pair
WHERE
e_sentence LIKE '%' || 'how often' || '%'
GROUP BY
e_sentence)
AS Parents JOIN Partials
ON Parents._id=ParentId
UNION
SELECT
e_sentence
FROM
Parents
The key part I am trying to accomplish is at the bottom, where I try to UNION a table created in the previous statement. Is there a way to do this in SQLite, or am I forced to repeat the query that made the Parents table in the first half of the UNION?
In SQLite 3.8.3 or later, you can use a common table expression:
WITH Parents AS (
SELECT e_sentence, _id
FROM Pair
JOIN PairCategories
...
)
SELECT Partials.e_sentence
FROM Parents
JOIN Partials ON Parents._id = ParentId
UNION
SELECT e_sentence
FROM Parents;
If you're using an older SQLite (probably because you're using an older Android), you can create a view for the subquery:
CREATE VIEW Parents AS
SELECT e_sentence, _id
FROM Pair
JOIN PairCategories
...;
SELECT Partials.e_sentence
FROM Parents
JOIN Partials ON Parents._id = ParentId
UNION
SELECT e_sentence
FROM Parents;
If you do not want to have this view permanently in the database, you could make it temporary (CREATE TEMPORARY VIEW ...) so that it is not available outside the current database connection, or, as last resort, you could just insert the subquery wherever you would use Parent:
SELECT Partials.e_sentence
FROM (SELECT ...) AS Parents
JOIN Partials ON Parents._id = ParentId
UNION
SELECT e_sentence
FROM (SELECT ...) AS Parents;

How can I see the last SQL statement executed in Oracle database 11g r2?

I am new to oracle database.
Can someone give me an example of the steps for how to see the last statements executed on the Oracle database 11g r2?
You can use the below query to get the last sql executed based on last sql which was active in database
select ltrim(sq.sql_text)
from v$sql sq, v$session se, v$open_cursor oc
where sq.sql_id = oc.sql_id
and se.saddr = oc.saddr
and se.sid = oc.sid
and se.audsid = SYS_CONTEXT('userenv', 'sessionid')
order by oc.LAST_SQL_ACTIVE_TIME desc;
You can also use the below to find the last query executed in your session.
SELECT (SELECT t2.sql_fulltext
FROM v$sql t2
WHERE t1.prev_sql_id = t2.sql_id
AND t1.prev_child_number = t2.child_number) sql_fulltext
FROM v$session t1
WHERE t1.audsid = Sys_context('userenv', 'sessionid');
You can use the below query:
SELECT program_id, program_line#, sql_text
FROM V$SQL VS , ALL_USERS AU
WHERE (executions >= 1)
AND (parsing_user_id != 0)
AND (AU.user_id(+) = VS.parsing_user_id)
AND UPPER(AU.USERNAME) IN (UPPER('YourUser'))
ORDER BY last_active_time DESC;
if you need to know the statements of an PL/SQL object were executed then use or join with
select *
from dba_objects
where object_id = program_id
Find all sql where sql is like ....
select h.sample_time
, u.username
, h.machine
, s.sql_text
, h.*
from dba_hist_active_sess_history h
inner join v$sql s
on s.sql_id = h.sql_id
left outer join dba_users u
on u.user_id = h.user_id
where s.sql_text like 'DELETE%'
order by h.sample_time desc;
You need to be connected as sysdba user for this sql
A couple of hints:
In SQLplus, type a semicolon+ to see, and slash to execute again
In SQLdeveloper, use F8
If you mean see other users' statements then it's not possible by default.
You can configure AUDIT.
You can see some SQL statements in SELECT * FROM V$SQLAREA;
Connect as SYS user and execute the following query
select sql_text from v$sql where first_load_time=(select max(first_load_time) from v$sql) ;
select sq.PARSING_SCHEMA_NAME, sq.LAST_LOAD_TIME, sq.ELAPSED_TIME, sq.ROWS_PROCESSED, ltrim(sq.sql_text)
from v$sql sq, v$session se
where sq.PARSING_SCHEMA_NAME = 'YOUR_SCHEMA'
order by sq.LAST_LOAD_TIME desc;

Is it possible to use WHERE clause in same query as PARTITION BY?

I need to write SQL that keeps only the minimum 5 records per each identifiable record in a table. For this, I use partition by and delete all records where the value returned is greater than 5. When I attempt to use the WHERE clause in the same query as the partition by statement, I get the error "Ordered Analytical Functions not allowed in WHERE Clause". So, in order to get it to work, I have to use three subqueries. My SQL looks ilke this:
delete mydb.mytable where (field1,field2) in
(
select field1,field2 from
(
select field1,field2,
Rank() over
(
partition BY field1
order by field1,field2
) n
from mydb.mytable
) x
where n > 5
)
The innermost subquery just returns the raw data. Since I can't use WHERE there, I wrapped it with a subquery, the purpose of which is to 1) use WHERE to get records greater than 5 in rank and 2) select only field1 and field2. The reason why I select only those two fields is so that I can use the IN statement for deleting those records in the outermost query.
It works, but it appears a bit cumbersome. I'd like to consolidate the inner two subqueries into a single subquery. Is this possible?
Sounds like you need to use the QUALIFY clause which is the HAVING clause for Window Aggregate functions. Below is my take on what you are trying to accomplish.
Please do not run this SQL directly against your production data without first testing it.
/* Physical Delete */
DELETE TGT
FROM MyDB.MyTable TGT
INNER JOIN
(SELECT Field1
, Field2
FROM MyDB.MyTable
QUALIFY ROW_NUMBER() (PARTITION BY Field1, ORDER BY Field1,2)
> 5
) SRC
ON TGT.Field1 = SRC.Field1
AND TGT.Field2 = SRC.Fileld2
/* Logical Delete */
UPDATE TGT
FROM MyDB.MyTable TGT
,
(SELECT Field1
, Field2
FROM MyDB.MyTable
QUALIFY ROW_NUMBER() (PARTITION BY Field1, ORDER BY Field1,2)
> 5
) SRC
SET Deleted = 'Y'
/* RecordExpireDate = Date - 1 */
WHERE TGT.Field1 = SRC.Field1
AND TGT.Field2 = SRC.Fileld2

dynamic table name in a query

How can I put a table name dynamically in a query?
Suppose I have a query as shown below:
Select a.amount
,b.sal
,a.name
,b.address
from alloc a
,part b
where a.id=b.id;
In the above query I want to use a table dynamically (part b if the database is internal, p_part b if the database if external).
I have a function that returns which database it is. Suppose the function is getdatabase();
select decode(getdatabase(),'internal','part b','external','p_part b')
from dual;
How can I use this function in my main query to insert the table name dynamically into the query?
I don't want to implement this using the primitive way of by appending strings to make a final query and then open cursor with that string.
I don't want to implement this with primitive way of by appending
strings to make a final query and then open cursor with that string .
That's really the only way you can do it. It's not possible to use a variable or function call for the table name when using a regular PL/SQL SQL block, you have to use dynamic SQL.
Refer to Oracle documentation for more details:
http://docs.oracle.com/cd/B10500_01/appdev.920/a96590/adg09dyn.htm
Here's an example from the doc:
EXECUTE IMMEDIATE 'SELECT d.id, e.name
FROM dept_new d, TABLE(d.emps) e -- not allowed in static SQL
-- in PL/SQL
WHERE e.id = 1'
INTO deptid, ename;
You can do this without dynamic SQL, assuming both tables (part and p_part) are available at compile time:
select a.amount
,b.sal
,a.name
,b.address
from alloc a
,part b
where a.id=b.id
and (select getdatabase() from dual) = 'internal'
UNION ALL
select a.amount
,b.sal
,a.name
,b.address
from alloc a
,p_part b
where a.id=b.id
and (select getdatabase() from dual) = 'external'
;
I've put the function call in a subquery so that it is run only once per call (i.e. twice, in this instance).

Resources