Using Join and Between to Link Tables and Find Values - sql

I am trying to join these two tables and get a result, keep all results from Table 1 and find the value from Table 2 (return NULL if nothing is found in Table 2 matching criteria)
TABLE1
|ROUTE|MEASURE|
|:---:|:-----:|
|1|6|
|1|12|
|2|1|
|3|2|
|3|5|
TABLE2
|ROUTE|BEGINMEASURE|ENDMEASURE|VALUE|
|:---:|:-----:|:--:|:--:|
|1|0|5|A|
|1|5|10|B|
|2|0|5|C|
|3|0|3|D|
|3|3|10|E|
|3|10|12|F|
My code is:
select t1.route, t1.measure, t2.value
from table1 t
left join table2 t2 on t1.route=t2.route
where t1.route=t2.route and t1.measure between t2.beginmeasure and t2.endmeasure;

Add the condition to the join:
select t1.route, t1.measure, t2.value
from table1 t
left join table2 t2 on t1.route=t2.route and t1.measure between t2.beginmeasure and t2.endmeasure;

Related

Fectch uncommon ID between two columns

I have two tables and I need to fetch if any one ID is not present in the table 2. I tried the query but its not giving the correct result. Kindly suggest.
TABLE 1
TABLE 2
Output Should be: Because Release ID and purchase ID is not present in both the columns.
QUERY Tried :
SELECT T1_ID
FROM T1 LEFT OUTER JOIN T2
ON t1.RELEASEID=t2.RELEASEID
LEFT OUTER JOIN T2 t3
ON t1.PURCHASEID=t3.PURCHASEID
WHERE IFNULL(T2.RELEASEID,'') ='' OR IFNULL(T3.PURCHASEID,'')=''
You can use NOT EXISTS as follows:
select * from t1
where not exists (select 1 from t2
where t1.releaseid =t2.releaseid or t1.purchaseid =t2.purchaseid)
You can also use LEFT JOIN as follows:
select t1.*
from t1 left join t2
on t1.releaseid =t2.releaseid or t1.purchaseid =t2.purchaseid
where t2.t2_id is null
One method is not exists:
select t1.*
from t1
where not exists (select 1
from t2
where t2.releaseid = t1.releaseid
) and
not exists (select 1
from t2
where t2.purchaseid = t1.purchaseid
);
This should work regardless of whether ? is really a string or is supposed to represent NULL.
Note: This can take advantage of indexes on t2(releaseid) and t2(purchaseid), which can be a big boost to performance on larger data.
I think you want:
select t1.*
from table1 t1
where
(t1.release_id = '?' and t2.purchase_id = '?')
or not exists (
select 1
from table2 t2
where t1.release_id in ('?', t2.release_id)
and t1.purchase_id in ('?', t2.purchase_id)
)
If the question mark is supposed to represent null values, you can just replace all instances of = '?' with is null.
Please try this and let me know if it works.
SELECT * FROM TABLE1 WHERE NOT EXISTS (SELECT '1' FROM TABLE2 WHERE TABLE1 .RELEASEID=TABLE2.RELEASEID OR TABLE1 .PURCHASEID=TABLE2.PURCHASEID);

Return data when the OR operator conditions are true in sql server

I have the following query. Currently it checks on two conditions:
if one condition is true it will return the results for the first statement (t1.ticket=t2.ticket and ( t1.type=t2.type)
if this result is false then it will return results for the next condition ( t1.code=t2.code).
It does this is because sometimes this condition columns (t1.ticket=t2.ticket and ( t1.type=t2.type)) are equal to null and some times this condition colums ( t1.code=t2.code) are null thats why it switches between both.
But now what i noticed is that sometimes both the conditions return true and because of the OR statement its ignoring one of the conditions.
How do i return results for both of those conditions if they both there conditions are met? If its not met then they must return the one condition that matches.
select t1.name
,t1.ID
,t1.type
,t2.TicketID
,t2.Account
,t1.code
from table 1 t1
inner join table 2 t2
on (t1.ticketID=t2.ticketID and t1.type=t2.type)
or ( t1.code=t2.code)
left join table 3 t3
on t2.Res=t3.res
left join table 4 t4
on t3.IdDetail=t4.idDetail
you can try by using left join
select t1.name
,t1.ID
,COALESCE(t2.Ticket,t22.Ticket) as Ticket
,COALESCE(t2.Account,t22.Account) as Account
,COALESCE(t2.code,t22.code) as code
,t22.type
,t3.res
,t1.type
from table1 t1 left join table2 t2 on (t1.ticket=t2.ticket and t1.code=t2.code)
left join t22 on ( t1.type=t22.type)
left join table3 t3 on t2.Res=t3.res
left join table4 t4 on t3.IdDetail=t4.idDetail
If you want both result of table2 then no need use COALESCE function
My suggestion is to add a calculated column as hash of ticket, on both table1 and table2 code and type on all the tables, then using it as a new 'surrogate' key, a trigger to generate it each time a row is updated.
ALTER TABLE T1 ADD
NEW_KEY AS (hashbytes('SHA1',CONCAT(TICKET,CODE,TYPE)))
ALTER TABLE T2 ADD
NEW_KEY AS (hashbytes('SHA1',CONCAT(TICKET,CODE,TYPE)))
UPDATE TABLE T2 SET NEW_KEY = hashbytes('SHA1',CONCAT(TICKET,CODE,TYPE)) WHERE NEW_KEY IS NULL
UPDATE TABLE T1 SET NEW_KEY = hashbytes('SHA1',CONCAT(TICKET,CODE,TYPE)) WHERE NEW_KEY IS NULL

Convert NOT IN query to LEFT JOIN

to adapt to Netezza DB I need to convert fallowing query(as NOT IN(SUBQUERY) is not supported by Netezza):
UPDATE table1 t1 SET t1.deal_type=t2.deal_type
FROM table2 t2
WHERE t1.id_col=t2.id_col
AND t1.price=t2.price
AND t1.id_col2=t2.id_col2
AND t2.price NOT IN (
SELECT st1.price
FROM table1 st1, table2 st2
WHERE st1.id_col=st2.id_col
AND st1.price=st2.price
AND st1.id_col2=st2.id_col2
AND st1.id_col=t1.id_col
AND t2.deal_type=st2.deal_type
GROUP BY st1.id_col, st1.price, st1.id_col2, st2.deal_type
HAVING COUNT (*)>1);
I tried with LEFT JOIN but not all records returned:
UPDATE table1 t1 SET t1.deal_type = t2.deal_type
FROM table2 t2
LEFT JOIN
(SELECT st1.price, st1.id_col, st2.deal_type
FROM table1 st1, table2 st2
WHERE st1.id_col=st2.id_col
AND st1.price=st2.price
AND st1.id_col2=st2.id_col2
GROUP BY st1.id_col, st1.price, st1.id_col2, st2.deal_type
HAVING COUNT (*)>1) subq ON (subq.id_col=t1.id_col
AND t2.deal_type=subq.deal_type)
WHERE
t1.id_col=t2.id_col
AND t1.price=t2.price
AND t1.id_col2=t2.id_col2
subq.price is null
Any suggestions where I was wrong. or any other way to work arround NOT IN witch is not supported by NETEZZA
I think you forgot to add the price to the Left Join condition.
if there are duplicates for this id&type but with different price,
the NOT-IN condition will pass, but the Left-Join (IS NULL) condition will fail
just change
ON (subq.id_col=t1.id_col
AND t2.deal_type=subq.deal_type)
to
ON (subq.id_col=t1.id_col
AND t2.deal_type=subq.deal_type)
AND subq.price=t2.price)
Can you please try this if netezza support EXISTS and your first query is logically right
UPDATE t1 SET t1.deal_type=t2.deal_type
FROM table1 t1
INNER JOIN table2 t2 ON t1.id_col=t2.id_col
AND t1.price=t2.price
AND t1.id_col2=t2.id_col2
LEFT JOIN ( SELECT st1.id_col
FROM table1 st1
INNER JOIN table2 st2 ON st1.id_col=st2.id_col
AND st1.price=st2.price
AND st1.id_col2=st2.id_col2
AND t2.deal_type=st2.deal_type
GROUP BY st1.id_col, st1.price, st1.id_col2, st2.deal_type
HAVING COUNT (*)>1) i ON i.id_col=t1.id_col
WHERE i.id_col IS NULL

sql simple 3 table join using same table?

I have two tables:
Table 1
id, name1
Table 2
id, name2a, name2b
Table 2's column names name2a, and name2b are references to table 1's id. I need to create a query that pulls both the names out of table 1 based on the id's used in Table 2.
Therefore, if Table one contained:
1 Peter
2 Paul
And Table 2 contained:
1 1 2
2 2 2
Then a select statement should give me:
Peter Paul
Paul Paul
I've gone around the bend trying to build this SQL and the best I came up with was:
SELECT table1.name AS 'name', table1.name AS 'Other name'
FROM table1, table2
WHERE table1.id = table2.name2a
Which only gives me the name2a column correctly.
Any help appreciated! I guess I need to do a join, but I'm really struggling...
Start with your 2nd table and join TWICE to table 1 (different aliases respectively), then get the name field from each aliased Table1 entry.
select
T2.ID,
TJ1.Name1 as FirstName,
TJ2.Name1 as SecondName
from
Table2 t2
join Table1 TJ1
on t2.Name2a = TJ1.ID
join Table1 TJ2
on t2.Name2b = TJ2.ID
select foo.*, t1.x, t2.y
join t1 on t1.id = foo.a
join t1 as t2 on t2.id = foo.b
If there's a chance that col a or col b is null, use a left join.
Have you tried using an INNER JOIN?
SELECT table1.name AS 'name', table1.name AS 'Other name'
FROM table1 INNER JOIN table2 ON table1.id = table2.name2a;
Sorry if I'm no help, not that great at SQL myself hehe.
Your problem is that you need to reference table1 twice: once for the plain table1.name and again to look up what table2 is pointing at. You can join one table in multiple times if you give them aliases:
SELECT t1.name1, o.name1
FROM table1 t1
JOIN table2 t2 ON t1.id = t2.name2a
JOIN table1 o ON t2.name2b = o.id -- And JOIN back to table1 to get the name1

Are "from Table1 left join Table2" and "from Table2 right join Table1" interchangeable?

For example, there are two tables:
create table Table1 (id int, Name varchar (10))
create table Table2 (id int, Name varchar (10))
Table1 data as follows:
Id Name
-------------
1 A
2 B
Table2 data as follows:
Id Name
-------------
1 A
2 B
3 C
If I execute both below mentioned SQL statements, both outputs will be the same:
select *
from Table1
left join Table2 on Table1.id = Table2.id
select *
from Table2
right join Table1 on Table1.id = Table2.id
Please explain the difference between left and right join in the above SQL statements.
Select * from Table1 left join Table2 ...
and
Select * from Table2 right join Table1 ...
are indeed completely interchangeable. Try however Table2 left join Table1 (or its identical pair, Table1 right join Table2) to see a difference. This query should give you more rows, since Table2 contains a row with an id which is not present in Table1.
Table from which you are taking data is 'LEFT'.
Table you are joining is 'RIGHT'.
LEFT JOIN: Take all items from left table AND (only) matching items from right table.
RIGHT JOIN: Take all items from right table AND (only) matching items from left table.
So:
Select * from Table1 left join Table2 on Table1.id = Table2.id
gives:
Id Name
-------------
1 A
2 B
but:
Select * from Table1 right join Table2 on Table1.id = Table2.id
gives:
Id Name
-------------
1 A
2 B
3 C
you were right joining table with less rows on table with more rows
AND
again, left joining table with less rows on table with more rows
Try:
If Table1.Rows.Count > Table2.Rows.Count Then
' Left Join
Else
' Right Join
End If
You seem to be asking, "If I can rewrite a RIGHT OUTER JOIN using LEFT OUTER JOIN syntax then why have a RIGHT OUTER JOIN syntax at all?" I think the answer to this question is, because the designers of the language didn't want to place such a restriction on users (and I think they would have been criticized if they did), which would force users to change the order of tables in the FROM clause in some circumstances when merely changing the join type.
select fields
from tableA --left
left join tableB --right
on tableA.key = tableB.key
The table in the from in this example tableA, is on the left side of relation.
tableA <- tableB
[left]------[right]
So if you want to take all rows from the left table (tableA), even if there are no matches in the right table (tableB), you'll use the "left join".
And if you want to take all rows from the right table (tableB), even if there are no matches in the left table (tableA), you will use the right join.
Thus, the following query is equivalent to that used above.
select fields
from tableB
right join tableA on tableB.key = tableA.key
Your two statements are equivalent.
Most people only use LEFT JOIN since it seems more intuitive, and it's universal syntax - I don't think all RDBMS support RIGHT JOIN.
I feel we may require AND condition in where clause of last figure of Outer Excluding JOIN so that we get the desired result of A Union B Minus A Interaction B.
I feel query needs to be updated to
SELECT <select_list>
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.Key = B.Key
WHERE A.Key IS NULL AND B.Key IS NULL
If we use OR , then we will get all the results of A Union B
select *
from Table1
left join Table2 on Table1.id = Table2.id
In the first query Left join compares left-sided table table1 to right-sided table table2.
In Which all the properties of table1 will be shown, whereas in table2 only those properties will be shown in which condition get true.
select *
from Table2
right join Table1 on Table1.id = Table2.id
In the first query Right join compares right-sided table table1 to left-sided table table2.
In Which all the properties of table1 will be shown, whereas in table2 only those properties will be shown in which condition get true.
Both queries will give the same result because the order of table declaration in query are different like you are declaring table1 and table2 in left and right respectively in first left join query, and also declaring table1 and table2 in right and left respectively in second right join query.
This is the reason why you are getting the same result in both queries. So if you want different result then execute this two queries respectively,
select *
from Table1
left join Table2 on Table1.id = Table2.id
select *
from Table1
right join Table2 on Table1.id = Table2.id
Select * from Table1 t1 Left Join Table2 t2 on t1.id=t2.id
By definition: Left Join selects all columns mentioned with the "select" keyword from Table 1 and the columns from Table 2 which matches the criteria after the "on" keyword.
Similarly,By definition: Right Join selects all columns mentioned with the "select" keyword from Table 2 and the columns from Table 1 which matches the criteria after the "on" keyword.
Referring to your question, id's in both the tables are compared with all the columns needed to be thrown in the output. So, ids 1 and 2 are common in the both the tables and as a result in the result you will have four columns with id and name columns from first and second tables in order.
*select *
from Table1
left join Table2 on Table1.id = Table2.id
The above expression,it takes all the records (rows) from table 1 and columns, with matching id's from table 1 and table 2, from table 2.
select *
from Table2
right join Table1 on Table1.id = Table2.id**
Similarly from the above expression,it takes all the records (rows) from table 1 and columns, with matching id's from table 1 and table 2, from table 2. (remember, this is a right join so all the columns from table2 and not from table1 will be considered).