(Oracle) Multiple WITH Clauses Referencing Each Other - sql

We are rewriting a SQL script originally containing 6 CREATE/REPLACE VIEW's, because our new app can't create objects in the DB. To rewrite it, we are using the WITH keyword.
The problem is, the original views referenced each other. Will this be allowed in Oracle:
with
A as (select T1COL from Table1 ...),
B as (select NEWCOL from A ...) ,
..

The answer is: yes, it is possible.
Due to the large amount of code involved it's not feasible to quickly try it. One would hope a quick response wouldn't be too difficult
I've prepared a runnable test for you:
http://sqlfiddle.com/#!4/9eecb7d/7884
WITH
a AS ( SELECT 'A' as T1COL FROM dual ),
b AS ( SELECT * FROM a ),
c AS ( SELECT * FROM b ),
d AS ( SELECT * FROM c ),
e AS ( SELECT * FROM d ),
f AS ( SELECT * FROM e ),
g AS ( SELECT * FROM f ),
h AS ( SELECT * FROM g ),
i AS ( SELECT * FROM h ),
j AS ( SELECT * FROM i ),
k AS ( SELECT * FROM j ),
l AS ( SELECT * FROM k ),
m AS ( SELECT * FROM l ),
n AS ( SELECT * FROM m ),
o AS ( SELECT * FROM n ),
p AS ( SELECT * FROM o ),
q AS ( SELECT * FROM p )
SELECT * FROM q;

Related

My query has a NOT IN, and suddenly stopped showing results

I have a query that runs every day, and suddenly it stopped outputting results. It doesn't output an error, just no results.
Note that this query includes a NOT IN operator.
This is a known problem of NOT IN behavior, check out the MySQL version of it:
MySQL "Not IN" query suddenly stopped returning results
With BigQuery:
WITH data AS (
SELECT * FROM UNNEST([1,2,3]) x
), data2 AS (
SELECT * FROM UNNEST([1,2]) x
)
SELECT * FROM data
WHERE x NOT IN (SELECT * FROM data2)
3
But then if you have a null in data2:
WITH data AS (
SELECT * FROM UNNEST([1,2,3]) x
), data2 AS (
SELECT * FROM UNNEST([1,2,null]) x
)
SELECT * FROM data
WHERE x NOT IN (SELECT * FROM data2)
# no results
Instead you could do a LEFT JOIN, or a NOT EXISTS:
WITH data AS (
SELECT * FROM UNNEST([1,2,3]) x
), data2 AS (
SELECT * FROM UNNEST([1,2]) x
)
SELECT * FROM data a
WHERE NOT EXISTS (SELECT * FROM data2 b WHERE a.x=b.x)
3

How can I turn a select statement that includes an except into an Ordered table?

Here is my example:
select * into temp from
select *, 'I' as flag from (
select * from A
except
select * from B ) a
union
select *, 'D' as flag from (
select * from B
except
select * from A ) b
ORDER BY X1,X2
This is the answer -
select * into dbo.temp from
(select *, 'I' as flag from (
select * from dbo.A
except
select * from dbo.B ) a
union
select *, 'D' as flag from (
select * from dbo.B
except
select * from dbo.A ) b
) as C
ORDER BY X1,X2
-- Remove temp table after use
DROP TABLE temp

How to call a sql query and pass a parameter from another table?

I have a complex sql query, named qryARAT2B_EXT.
SELECT
*
FROM
(
SELECT
*
FROM
(
SELECT
*,
firstStudy,
ABS(DATEDIFF('d', firstStudy, Check_Date)) as diff
FROM
(
SELECT
*,
(
SELECT
TOP 1 Check_Date
FROM
qryARAT2B
WHERE
PATNR = [PАРАМ]
ORDER BY
Check_Date
)
AS firstStudy
FROM
(
SELECT
*
FROM
qryARAT2B
WHERE
PATNR = [PАРАМ]
)
AS myPatientsWithStudy
)
AS myPatientsFirstStudy
)
WHERE
diff = 0
)
AS T1
LEFT JOIN
(
SELECT
*
FROM
(
SELECT
*,
firstStudy,
ABS(DATEDIFF('d', firstStudy, Check_Date)) as diff
FROM
(
SELECT
*,
(
SELECT
TOP 1 Check_Date
FROM
qryARAT2B
WHERE
PATNR = [PАРАМ]
ORDER BY
Check_Date
)
AS firstStudy
FROM
(
SELECT
*
FROM
qryARAT2B
WHERE
PATNR = [PАРАМ]
)
AS myPatientsWithStudy
)
AS myPatientsFirstStudy
)
WHERE
diff = 4
)
As T2
ON T1.PATNR = T2.PATNR
When I open it in ms-access, it asks for the value of the [PARAM] and produces the result.
I have a table of patients.
tblPatient with the columns:
PATNR, and s.o.
That contains the PATNR's of patients:
000001
000002
...
XXXXXX
I need to write sql to calculate data for all PATNR's at once.
something like this:
SELECT (SELECT * FROM qryARAT2B_EXT WHERE [PARAM] = PATNR) from tblPatient
But it is not accepted from ms-access. I'm not able to pass parameter to qryARAT2B_EXT from the SQL. Is there any specific syntax for it in ms-access?

Custom pagination in Oracle

Can anyone suggest whether the below query format is correct?
SELECT *
FROM ( SELECT b.*
, ROW_NUMBER() OVER (Order by b.TEST_NO) R
FROM ( select r.*
from ( select TEST_NO , TEST_NO1, TEST_NO2
From test_table
where TEST_NO2 = '0000as23') r
where 1 = 1
and rownum < 10000 ) b
)
WHERE R BETWEEN 11 and 200;
Here I am trying to achieve custom pagination using Oracle syntax.

Distinct select on Oracle

What i am trying to do is a simple recommender , must take the biggest weighted top 40 element's node2 element. Calculation for weight comes from (E.WEIGHT * K.GRADE). Now this code succesfully returns top 40 elements. However, i don't want E.NODE2 to return duplicates. POSTGRE SQL allowed me to do SELECT DISTINCT ON (NODE2) E.NODE2 , (E.WEIGHT * K.GRADE). How can i do the same in oracle?
The complete sql query;
SELECT *
FROM (SELECT DISTINCT E.NODE2 , (E.WEIGHT * K.GRADE)
FROM KUAISFAST K, EDGES E
WHERE K.ID = 1 AND K.COURSE_ID = E.NODE1 AND E.NODE2 NOT IN(
SELECT K2.COURSE_ID
FROM KUAISFAST K2
WHERE K2.ID = 1
)
ORDER BY( E.WEIGHT * K.GRADE ) DESC) TEMP
WHERE rownum <= 40
This should solve your problem, altough quite slow
SELECT * FROM
(SELECT *
FROM (SELECT E.NODE2 , max(E.WEIGHT * K.GRADE ) AS MAXDE
FROM KUAISFAST K, EDGES E
WHERE K.ID = 1 AND K.COURSE_ID = E.NODE1 AND E.NODE2 NOT IN(
SELECT K2.COURSE_ID
FROM KUAISFAST K2
WHERE K2.ID = 1
)
GROUP BY E.NODE2 )
ORDER BY MAXDE DESC)
WHERE rownum <= 40
I believe you want something like
SELECT *
FROM (
SELECT
E.NODE2,
(E.WEIGHT * K.GRADE),
ROW_NUMBER() OVER (PARTITION BY E.NODE2 ORDER BY E.WEIGHT * K.GRADE DESC) R
FROM
KUAISFAST K,
EDGES E
WHERE
K.ID = 1 AND
K.COURSE_ID = E.NODE1 AND
E.NODE2 NOT IN
( SELECT K2.COURSE_ID
FROM KUAISFAST K2
WHERE K2.ID = 1
)
ORDER BY (E.WEIGHT * K.GRADE) DESC
) TEMP
WHERE R=1 AND
ROWNUM <= 40
In your subselect, I think you want: MAX(E.WEIGTH * K.GRADE) so that only one value comes back for each E.NODE2.
This means you'll need to GROUP BY E.NODE2 as well.