Oracle SQL - Define table names for later usage? - sql

I wanted to know if there is a way, in SQL Oracle, to do some range-definition (like in Excel). For example:
DEFINE TABLE1 = SELECT FIELD1, FIELD2, FIELD3 FROM [SCHEMA].[TABLE0][WHERE/GROUP BY/HAVING/ORDER BY/...];
DEFINE TABLE2 = SELECT FIELD1, FIELD2, FIELD3 FROM TABLE1 [WHERE/GROUP BY/HAVING/ORDER BY/...];
DEFINE TABLE3 = SELECT FIELD1, FIELD2, FIELD3 FROM TABLE2 LEFT JOIN TABLE1 ON [CONDITIONS];
SELECT * FROM TABLE3;
Thanks a lot in advance.

Based on your examples, it sounds like you want to create views:
CREATE VIEW TABLE1 AS
SELECT FIELD1, FIELD2, FIELD3
FROM [SCHEMA].[TABLE0][WHERE/GROUP BY/HAVING/...];
CREATE VIEW TABLE2 AS
SELECT FIELD1, FIELD2, FIELD3
FROM TABLE1 [WHERE/GROUP BY/HAVING/...];
CREATE VIEW TABLE3 AS
SELECT FIELD1, FIELD2, FIELD3
FROM TABLE2
LEFT JOIN TABLE1 ON [CONDITIONS];
SELECT * FROM TABLE3;

TO close this question. From one of the comments (Steve), what I needed is a WITH clause, as I didn't have DDL privileges.
Thanks,

Related

How can do subscription between two SELECT set?

SELECT field1
FROM tbl1
WHERE conditionsx
...?
SELECT field2
FROM tbl2
WHERE conditionsy
I Want return same below↓
What is superscription between two SELECT results.
You can use the INTERSECT operator:
SELECT field1 FROM tbl1 WHERE conditionsx
INTERSECT
SELECT field2 FROM tbl2 WHERE conditionsy

How to add 2 columns to existing query result based on another query?

I have a query like this:
SELECT
field1 as field1 ,
field2 as field2 ,
(select count(*) from ... where ...=field1) as field3
FROM
...
And it works fine - and I see 3 columns in results
The I need to add one more column for internal query:
SELECT
field1 as field1 ,
field2 as field2 ,
(select count(*) as my_count, sum(*) as my _sum from ...where ...=field1 ) as field3
FROM
...
this syntax doesn't work.
How can I achieve it ?
This partial query makes it unsure what you really want, but I would expect that the subquery actually correlates to the outer query (otherwise, you could just cross join). If so, a typical solution is a lateral join.
In Postgres:
select
field1 as field1,
field2 as field2,
x.*
from ...
left join lateral (
select count(*) as my_count, sum(*) as my _sum from ...
) x
Oracle supports lateral joins starting version 12. You just need to replace left join lateral with outer apply.
The following would seem to do what you want, and it should work fine in Oracle 9i:
SELECT t.field1,
t.field2,
x.my_count,
x.my_sum
FROM SOME_TABLE t
LEFT OUTER JOIN (select FIELD1,
count(*) as my_count,
sum(SOME_FIELD) as my_sum
from SOME_OTHER_TABLE
GROUP BY FIELD1) x
ON x.FIELD1 = t.FIELD1
You can use a CTE (Common Table Expression) to precompute the values:
WITH
q as (select count(*) as my_count, sum(*) as my _sum from ... )
SELECT
field1 as field1 ,
field2 as field2 ,
q.my_count as field3,
q.my_sum as field4
FROM
...
CROSS JOIN q
Or... you can always use the less performant, simpler way:
SELECT
field1 as field1 ,
field2 as field2 ,
(select count(*) from ... ) as field3,
(select sum(*) from ... ) as field4
FROM
...
With your limited (& a bit confusing - 2 databases, sum(*) ...) info,
here is the logic:
SELECT
field1 as field1 ,
field2 as field2 ,
(select count(*) from ... ) as my_count,
(Select sum(<my field>) from ...) as my _sum
FROM
...

Oracle query where field1=field2 and field2=field1

So I have a table that holds a link relationship. Field1 is and ID and Filed2 is an ID. So far I've eliminated duplicate Field1\Field2 combinations. However I still have cases where the inverse occurs. Meaning Field1 occurs as Field2 and Field2 occurs in Field1 for the same record. I tried a subquery within in inner join but it's returning way to many rows. Thanks in advance!
select a.field1, a.field2 from linktable
inner join (select field1, field2 from linktable) b on a.field1=b.field2 and a.field2=b.field1;
Sample data:
insert into linktable(field1, field2) values ('ABC', '123');
insert into linktable(field1, field2) values ('123', 'ABC');
I want to identify and remove cases where the above sample data occurs.
Something like this should get you the pairs:
SELECT a.field1, a.field2
FROM linktable a
JOIN linktable b ON (b.field1 = a.field2 AND b.field2 = a.field1)
Edit: An example of finding one of the pairs:
create table linktable(id number, field1 varchar2(32), field2 varchar2(32));
insert into linktable(id, field1, field2) values (1, 'ABC', '123');
insert into linktable(id, field1, field2) values (2, '123', 'ABC');
SELECT a.field1, a.field2, LEAST(a.id, b.id) AS id_to_delete
FROM linktable a
JOIN linktable b ON (b.field1 = a.field2 AND b.field2 = a.field1);
Result:
FIELD1 FIELD2 ID_TO_DELETE
123 ABC 1
ABC 123 1
You should post sample data and expected result.
I think this query may work for you, this prevent the inverse occurs as field1, field2 = (x, y) and (y, x)
SELECT field1, field2
FROM linktable
WHERE field1 >= field2;
Is this what you want?
select field1, field2
from (select field1, field2,
row_number() over (partition by least(field1, field2), greatest(field1, field2) order by field1) as seqnum
from t
) t
where seqnum = 1;
This returns one instance of field1/field2 regardless of ordering.

Matching table between select in a function into a biggest select

I have to call a function into a select, and at the same time, i have to do a select into that function which is matching with the biggest select.
I try this but it doesn't work:
SELECT field1,
field2,
function(select field3 from table2 where table2.id = table1.id and table2.id = 3)
FROM table1
WHERE ...
How should i do the select into the function?
You should do a Union of results as
SELECT field1,
field2,
FROM table1
WHERE ...
Union All
Select function(select * from table2 where table2.id = table1.id) --function returning max

SQL advanced sub select query

I would like to expand on this simple sub select:
Select * from table1 where pkid in (select fkid from table2 where clause...)
The logic above is fairly simple - get me all rows in table1 where the pkid is contained in the subset returned from the sub select query that has a where clause. It works well because there is only 1 field being returned.
Now I want to expand on this.
In table 1 I want to return results where field1 and field2 and field3 in select (field1, field2, field3 from table2 where clause...)
How is this possible?
Thanks in advance.
Example.
TABLE1
FIELD1 FIELD2 FIELD3
1 2 3
2 3 4
4 5 6
TABLE 2
2 3 4
4 5 6
I want to return 2 results.
If I understand what you need you can try:
SELECT t1.field1, t1.field2, t1.field3 FROM table1 t1
INNER JOIN table2 t2
ON t1.field1 = t2.field1
AND t1.field2 = t2.field2
AND t1.field3 = t2.field3
AND t2.... // Use this as WHERE condition
Like Marco pointed out, what you want to do is an INNER JOIN.
But (that's just FYI, you should definitely use Marco's solution) it's also possible to simply use braces.
Select *
from table1
where (field1, field2, field3) in (select field1, field2, field3 from table2 where clause...)
At least in MySQL (wasn't this question tagged with MySQL?)
you can use a temporary table
select field1, field2, field3 into #tempTable from table2 where clause...
select * from table 1
where filed1 in (select field1 from #tempTable)
and filed2 in (select field2 from #tempTable)
and filed3 in (select field3 from #tempTable)
Avoid using IN for most cases like this. It's very limitting.
I prefer to use a JOIN in most cases.
SELECT
*
FROM
yourTable
INNER JOIN
(SELECT c1, c2, c3 FROM anotherQuery) AS filter
ON yourTable.c1 = filter.c1
AND yourTable.c2 = filter.c2
AND yourTable.c3 = filter.c3
(Ensure the filter returns unique combinations of c1, c2, c3 using DISTINCT or GROUP BY if necessary)
you didn't mentioned engine, so I'll assume SQL Server.
This query will show you what's on both tables
select FIELD1, FIELD2 from table1
intersect
select FIELD1, FIELD2 from table2