What does <> exactly do in a SQL self join? - sql

I'm new to SQL and I don't understand why you need a <> condition in a self join like below. I get that a join with an equal to condition won't return any results but I can't get my head around the need for <> in this case.
Please let me know if I need to provide any other info to answer this.
SELECT DISTINCT
t1.number AS num1,
t2.number AS num2
FROM transportation_numbers t1
JOIN transportation_numbers t2 ON t1.index <> t2.index
WHERE
t1.number < t2.number AND
t1.number * t2.number > 11

I've used it many times in things like self joins across one column that is not a unique identifier/key and then use the <> to prevent joining the same ID to itself.
Something like
SELECT a.id,
a.otherCol,
b.id,
b.otherCol
FROM T AS a INNER JOIN
T AS b ON b.someCol = a.someCol AND a.id <> b.id

This means that each row in a table is joined to itself and every other row in that table.
SELECT
A.LName AS Employee1
,B.LName AS Employee2
,A.City
FROM Employee A, Employee B
WHERE A.LName < B.LName
AND A.City = B.City
ORDER BY A.City;

Related

using where clause with Union

I have two tables, t1 and t2, with identical columns(id, desc) and data. But one of the columns, desc, might have different data for the same primary key, id.
I want to select all those rows from these two tables such that t1.desc != t2.desc
select a.id, b.desc
FROM (SELECT * FROM t1 AS a
UNION ALL
SELECT * FROM t2 AS b)
WHERE a.desc != b.desc
For example, if t1 has (1,'aaa') and (2,'bbb') and t2 has(1,'aaa') and (2,'bbb1') then the new table should have (2,'bbb') and (2,'bbb1')
However, this does not seem to work. Please let me know where I am going wrong and what is the right way to do it right.
Union is not going to compare the data.You need Join here
SELECT *
FROM t1 AS a
inner join t2 AS b
on a.id =b.id
and a.desc != b.desc
UNION ALL dumps all rows of the second part of the query after the rows produced by the first part of the query. You cannot compare a's fields to b's, because they belong to different rows.
What you are probably trying to do is locating records of t1 with ids matching these of t2, but different description. This can be achieved by a JOIN:
SELECT a.id, b.desc
FROM t1 AS a
JOIN t2 AS b ON a.id = b.id
WHERE a.desc != b.desc
This way records of t1 with IDs matching records of t2 would end up on the same row of joined data, allowing you to do the comparison of descriptions for inequality.
I want both the rows to be selected is the descriptions are not equal
You can use UNION ALL between two sets of rows obtained through join, with tables switching places, like this:
SELECT a.id, b.desc -- t1 is a, t2 is b
FROM t1 AS a
JOIN t2 AS b ON a.id = b.id
WHERE a.desc != b.desc
UNION ALL
SELECT a.id, b.desc -- t1 is b, t2 is a
FROM t2 AS a
JOIN t1 AS b ON a.id = b.id
WHERE a.desc != b.desc
The UNION operator is used to combine the result-set of two or more SELECT statements.
Notice that each SELECT statement within the UNION must have the same number of columns. The columns must also have similar data types.
So, if it has same number of columns and same datatype, then use Union otherwise join only Can be used.
SELECT *
FROM t1 AS a
inner join t2 AS b
on a.id =b.id
and a.desc != b.desc

SQL Where Null Values

I have two tables which I need to use a where clause.
Table1
CustomerID Product
1 Car
2 Table
3 Golf
4 Foo
5 Yoo
Table2
CustomeID Comment
2 Three items
3 Returned
4 Complaint
I have a query which has two filters in the where statement like this
Select * from table1 a left
join table2 b on a.customerid= b.customerid
where b.comment<>'Returned' and b.comment not like 'Three%'
When I ran the query I just got one record. I want it to also return the two customerID's which are not in table2(three records)
SELECT * FROM Table1 A
LEFT JOIN Table2 B
ON A.CustomerID=B.CustomeID
WHERE ( B.COMMENT<>'RETURNED' AND B.COMMENT NOT LIKE 'THREE%')
OR B.CustomeID IS NULL
This should work I guess.
Try:
SELECT *
FROM table1 a
LEFT JOIN table2 b on a.customerid= b.customerid
WHERE (b.comment<>'Returned' and b.comment not like 'Three%')
OR (b.customerid is NULL)
I think you need to use LEFT OUTER JOIN:
Select * from table1 a left outer join table2 b on a.customerid = b.customerid where b.comment<>'Returned' and b.comment not like 'Three%'
I usually tend not to JOIN that much.
SELECT --It's a good practice to enumerate all rows you need, not just *.
T1.CUSTOMERID,
T1.PRODUCT
FROM
TABLE1 T1
WHERE
T1.CUSTOMERID NOT IN (
SELECT
T2.CUSTOMERID
FROM
TABLE2 T2
WHERE
T2.COMMENT !='Returned' AND
T2.COMMENT not like 'Three%')

Select if else sql

I have two table say T1 and T2 and one column C is common to both. I need an SQL query in which if C is null in T1 it will select from other table.
I tried writing SELECT statement in THEN clause but not running. Don't know is there any IF ELSE clause in SQL.
Select C, case when c = null Then Select c from T2
from T1
Even better, most RDBMSs support COALESCE, which lets you check multiple values and return the first non-null value.
SELECT COALESCE(T1.C, T2.C) AS C
FROM T1
LEFT OUTER JOIN T2 ON T1.[Primary Key] = T2.[Primary Key]
Is this in TransactSQL?
I like the first answer, however you could also do it this way...
select case t1.C
when null then t2.C
else t1.C
end as [testC]
from t1
inner join t2
on t1.PKID = t2.PKID
What you seem to need is a union
select c from t1
where c is not null
union
select c from t2
where c is not null
Now you get all the columns C from T1and T2 in one result set but only if not null.
Well of course if this has simplified your problem too much you need to work with a join
select coalesce(t1.c,t2.c) as c
from t1
left join t2 on (t2.id = t1.foreign_id)
This assumed that T2.ID is the primary key and related to T1 with T1.FOREIGN_ID
It is important that you do a left join because otherwise you only get T1 rows when the row also exists in T2.

Join selections

How I can join this queries to single select (without temp table)?
SELECT t2.value,
t1.value
FROM table0 t1
INNER JOIN table1 t3 on t1.idrelation = t3.id and t3.idparent=#id
INNER JOIN table2 t2 on t2.idversion = t3.idchild and t2.name = 'FOO'
ORDER BY t1.value
SELECT SELECT COALESCE(t4._NAME+','+'')
FROM table1 t1
JOIN table1 t2 on t2.idparent = t1.idchild
JOIN table1 t3 on t3.idparent = t2.idchild
JOIN table3 t4 on t4._ID = t3.idchild
WHERE t1.idparent = #id
AND t4._TYPE ='TXT_CAT'
Something like this would help (once you can tell the columns on which you want to join):
select *
from
(
QUERY 1
) q1
join
(
QUERY 2
) q2
on q1.key1 = q2.key2
If you want to join them, there has to be common or uncommon ground.
Putting the 2 selects together is the easy part when you join the resultant sets, but unless you want all permutations of Ans1 and Ans2, then it is wise to determine some sort of where clause to allow it to be more effecient, and narrow it down for you.
If you give more table information, We could be able to adjust and give you something further, but that is the best we can do without taking arbitrary guesses as to what you are trying to accomplish here.
One thing i can part unto you:
Select A.name, B.id from (Select A.name, A.date from A) join (Select B.id, B.date from B) on A.date = B.date;

Semantic difference between join queries

I have two queries that I thought meant the same thing, but I keep getting different results and I was hoping someone could explain how these are different:
1.
select *
from table1 a
left join table2 b on a.Id = b.Id and a.val = 0
where b.Id is null
2.
select *
from table1 a
left join table2 b on a.Id = b.Id
where b.Id is null
and a.val = 0
The point of the query is to find the rows that are in table1 and val = 0 that are not in table2.
I'm using sql server 2008 as well, but I doubt that this should matter.
When considering left joins think of them as having 3 conceptual stages.
The join filter is applied
The left rows are added back in
the where clause is applied.
You will then see why you get different results.
That also explains why this returns results
select o.*
from sys.objects o
left join sys.objects o2 on o.object_id=o2.object_id and 1=0
And this doesn't.
select o.*
from sys.objects o
left join sys.objects o2 on o.object_id=o2.object_id
where 1=0
SELECT * from TABLE1 t1
WHERE Val = 0
AND NOT EXISTS(SELEct 1 from Table2 t2 Where t1.Id = t2.Id)
If you remove the WHERE clause entirely, using a LEFT OUTER JOIN means that all the rows from the table on the left hand side will appear, even if they don't satisfy the JOIN criteria. For example, no rows satisfy the expression 1 = 0 however this:
SELECT *
FROM table1 AS a
LEFT OUTER JOIN table2 AS b
ON a.Id = b.Id
AND 1 = 0;
still results in all rows in table1 being returned where the id values match. Simply put, that's the way OUTER JOINs work.
The WHERE clause is applied after the JOIN, therefore this
SELECT *
FROM table1 AS a
LEFT OUTER JOIN table2 AS b
ON a.Id = b.Id
WHERE 1 = 0;
will return no rows.