I would like to be able to run a self-inner join on the output of a query.
Performing an self INNER JOIN, in the simplest case, is easy:
SELECT *
FROM A a1 INNER JOIN
A a2 ON
a1.key = a2.key
The problem is that I need to do this self-inner join on the output of another inner join. Something like
SELECT *
FROM DATA.A A INNER JOIN
DATA.B B
ON A.key = B.key output /* output is the dataset I am interested in */
INNER JOIN
(FROM DATA.A A INNER JOIN
DATA.B B
ON A.key = B.key output2) /* same code to get output, so that I can self reference */
ON
OUTPUT.key_alt = OUTPUT2.key_alt
Is it possible to do so? I cannot store output in my database.
In SQL Server:
I prefer to use a common table expression for this sort of thing. It keeps things a more readable in my opinion.
with cte as (
select *
from data.A as A
inner join data.B as B
on A.key = B.key
)
select ...
from cte as o
inner join cte as i
on o.key = i.key
You can do achieve this with standard subqueries though.
select o.*
from (
select *
from data.A as A
inner join data.B as B
on A.key = B.key
) as o
inner join (
select *
from data.A as A
inner join data.B as B
on A.key = B.key
) as i
on o.key = i.key
Related
I have a query like this:
SELECT a.*
FROM a
LEFT JOIN b
ON b.a_id = a.id
LEFT JOIN c
ON c.a_id = a.id
LEFT JOIN (/* some complex subquery */) AS q
ON q.id = a.id OR q.id = b.id OR q.id = c.id
Obviously it's not optimal because using ORs in the ON condition makes the planner unable to use indexes.
I tried to rewrite it like this:
WITH (/* some complex subquery */) AS q
SELECT a.*
FROM a
LEFT JOIN q AS qa
ON qa.id = a.id
LEFT JOIN b
ON b.a_id = a.id
LEFT JOIN q AS qb
ON qb.id = b.id
LEFT JOIN c
ON c.a_id = a.id
LEFT JOIN q AS qc
ON qc.id = c.id
WHERE COALESCE(qa.id, qb.id, qc.id) IS NOT NULL
but it didn't get much faster because the database still needs to evaluate the WHERE clause.
Is there any technique to optimize such a kind of joins? If not, then how can I redesign the schema?
I have a query which involves a left join followed by a join. I want to make sure the left join is done first. The left join comes before the join nin my query, is this enough? This is how the join looks like
select * from
(select *....) A
left join
(select *...) B
on A.a = B.a
left join
C
on A.f = C.f
I cannot see the JOIN in your code, only two LEFT JOIN statements.
However, if you have something like this:
select * from
(select *....) A
left join
(select *...) B
on A.a = B.a
join
C
on A.f = C.f
and you want to make sure the LEFT JOIN is executed first, you can move this LEFT JOIN to a sub-query:
select *
from (
select * from (
(select *....) A
left join
(select *...) B
on A.a = B.a
)
) D
join
C
on D.f = C.f
I would like to add a field to a existing query that doesn't get affected from 'Where function'
For example,
This is the original code....
SELECT SHELL_Payables.PoolNum,
A.[Code], B.[Program] AS Program, A.PayableAmt, C.ReceivableAmt INTO [New Data]
FROM A INNER JOIN B ON A.ID=B.ID
INNER JOIN C ON A.Num=B.Num
WHERE (((A.AccountingPeriod)<=[AccountingYearMonth]));
I would like to add A.PayableAmt again but this time where clause (accountingperiod <= accountingyearMonth) should not be applied to this field...
Any ideas? It would be much appreciated.
To use union and select into, you would need to write your query something like this:
SELECT *
INTO [New Data]
FROM (
SELECT PoolNum
,A.[Code]
,B.[Program] AS Program
,A.PayableAmt
,C.ReceivableAmt
FROM A
INNER JOIN B ON A.ID = B.ID
INNER JOIN C ON A.Num = B.Num
WHERE A.AccountingPeriod <= AccountingYearMonth
UNION
SELECT PoolNum
,A.[Code]
,B.[Program] AS Program
,A.PayableAmt
,C.ReceivableAmt
FROM A
INNER JOIN B ON A.ID = B.ID
INNER JOIN C ON A.Num = B.Num
)
UPDATE
If you want to add another PayableAmt column to the same row, maybe you can join back to the table A something like this:
SELECT t.PoolNum
,a.[Code]
,a.[Program] AS Program
,t.PayableAmt
,a.PayableAmt AS NewPayableAmt
,C.ReceivableAmt
INTO [New Data]
FROM A
LEFT JOIN
(
SELECT
PoolNum
,A.[Code]
,B.[Program] AS Program
,A.PayableAmt
,C.ReceivableAmt
FROM A
INNER JOIN B ON A.ID = B.ID
INNER JOIN C ON A.Num = B.Num
WHERE A.AccountingPeriod <= AccountingYearMonth
) t
ON t.Code = A.Code --assuming this is unique
INNER JOIN B ON A.ID = B.ID
INNER JOIN C ON A.Num = B.Num
I want something like the following.
SELECT fewCols, aColFromNewTbl FROM TABLE_A AS A
LEFT OUTER JOIN TABLE_B AS B ON A.ID = B.ID
LEFT OUTER JOIN TABLE_C AS C ON A.ID = C.ID
INNER JOIN A_NEW_TABLE AS NEWTBL ON NEWTBL.ID = B.ID;
Somehow I'm not able to achieve this functionality. Actually above query is suppose to join A with NEWTBL, but I'm joining it with B, which is already joined with A. For my results I want them to come exclusively from the join of NEWTBL and B. I don't know how I can get desired results?
Probably you need this:
SELECT fewCols, aColFromNewTbl
FROM TABLE_A AS A
LEFT OUTER JOIN TABLE_B AS B
INNER JOIN A_NEW_TABLE AS NEWTBL
ON NEWTBL.ID = B.ID
ON A.ID = B.ID
LEFT OUTER JOIN TABLE_C AS C
ON A.ID = C.ID;
Working on Oracle: I am attempting to do an inner self join, with a where clause, then take that result and do a left outer join on it:
(select * from table1 A
inner join
select * from table1 B
on A.id = B.id
where
A.id is not null and B.id is not null) C
left outer join
select * from table2 D
on C.id = D.id
Somehow I am syntactically challenged and can't make this work. Can't seem to find the right syntax anywhere.
Just the put the where clause at the end. The database will get it right:
select *
from table1 A
inner join table1 B on A.id = B.id
left join table2 D on D.id = A.id
where A.id is not null
In this case, we can take advantage of the logical transitive property for your id column joins and where clause.
Your second join needs to be joined to a query add a select * from at the beginning
select * from (select * from table1 A
inner join
select * from table1 B
on A.id = B.id
where
A.id is not null and B.id is not null) C
left outer join
select * from table2 D
on C.id = D.id