sql compare two unique rows from the same table - sql

Im hoping this is a straight forward question but I cannot work out the syntax for it.
I just need to find if a value within "ID" also exists in "ID2", lets say the tables called "teacher"
ID-ID2
10-1
11-2
12-13
13-4
the only match there is row 4 as 13 also exists in id2, so I would need to pull that out with a select query, can anybody advise? thanks.
Hi on top of this I have a second table called staff with the following setup
ID-Name
1-smith
2-jones
3-bruce
whereby ID is the same ID as in the teacher table, I think I need to join them here but im not sure what to do with the ID in the second table. The only information I need from the second table is the name so the Cartesian product should look like the above only with the processing done from table 1. thanks in advance
scrap that, solved it, thanks

Is this what you want?
select t.*
from teacher t
where exists (select 1 from teacher t2 where t2.id = t.id2);

select *
from teacher
where id in (select distinct id2 from teacher)
or
select t1.*
from teacher t1
join teacher t2 on t1.id = t2.id2

select t1.*
from teacher as t1 ,teacher as t2
where t1.ID = t2.ID2 and t1.ID > t2.ID2

Related

SQL: Finding non-matches

my first table looks like the following (t1)
uid
car_id
s123
1234
p908
2345
q123
567
my second table looks like the following (t2):
uid
category
s123
honda
p908
mercedes
What I am trying to do is to find the uids (along with their car_id) from t1 that do not have a matching uid in t2. For example, the "q123" from t1 should be returned since it does not appear in t2. Any idea how this can be achieved?
Thank you!
SELECT uid, car_id
FROM t1
WHERE uid NOT IN (SELECT uid FROM t2 )
Using LEFT JOIN will bring back all the rows on the LEFT, regardless of a match on the right. Since you only want the non-matching, you could include only these in the WHERE clause.
SELECT t1.uid, t1.car_id, t2.category
FROM t1 LEFT JOIN t2 on t1.uid = t2.uid
WHERE t2.uid IS NULL
Or, you could use a NOT EXISTS
SELECT t1.uid, t1.car_id
FROM t1
WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE t1.uid = t2.uid)
I have never used Google Bigquery, but going off the docs here, the syntax looks just like MS SQL. Also, here's the SQL Fiddle if you need it.

Cross joining tables to see which partners in one table have a report from another table [duplicate]

table1 (id, name)
table2 (id, name)
Query:
SELECT name
FROM table2
-- that are not in table1 already
SELECT t1.name
FROM table1 t1
LEFT JOIN table2 t2 ON t2.name = t1.name
WHERE t2.name IS NULL
Q: What is happening here?
A: Conceptually, we select all rows from table1 and for each row we attempt to find a row in table2 with the same value for the name column. If there is no such row, we just leave the table2 portion of our result empty for that row. Then we constrain our selection by picking only those rows in the result where the matching row does not exist. Finally, We ignore all fields from our result except for the name column (the one we are sure that exists, from table1).
While it may not be the most performant method possible in all cases, it should work in basically every database engine ever that attempts to implement ANSI 92 SQL
You can either do
SELECT name
FROM table2
WHERE name NOT IN
(SELECT name
FROM table1)
or
SELECT name
FROM table2
WHERE NOT EXISTS
(SELECT *
FROM table1
WHERE table1.name = table2.name)
See this question for 3 techniques to accomplish this
I don't have enough rep points to vote up froadie's answer. But I have to disagree with the comments on Kris's answer. The following answer:
SELECT name
FROM table2
WHERE name NOT IN
(SELECT name
FROM table1)
Is FAR more efficient in practice. I don't know why, but I'm running it against 800k+ records and the difference is tremendous with the advantage given to the 2nd answer posted above. Just my $0.02.
SELECT <column_list>
FROM TABLEA a
LEFTJOIN TABLEB b
ON a.Key = b.Key
WHERE b.Key IS NULL;
https://www.cloudways.com/blog/how-to-join-two-tables-mysql/
This is pure set theory which you can achieve with the minus operation.
select id, name from table1
minus
select id, name from table2
Here's what worked best for me.
SELECT *
FROM #T1
EXCEPT
SELECT a.*
FROM #T1 a
JOIN #T2 b ON a.ID = b.ID
This was more than twice as fast as any other method I tried.
Watch out for pitfalls. If the field Name in Table1 contain Nulls you are in for surprises.
Better is:
SELECT name
FROM table2
WHERE name NOT IN
(SELECT ISNULL(name ,'')
FROM table1)
You can use EXCEPT in mssql or MINUS in oracle, they are identical according to :
http://blog.sqlauthority.com/2008/08/07/sql-server-except-clause-in-sql-server-is-similar-to-minus-clause-in-oracle/
That work sharp for me
SELECT *
FROM [dbo].[table1] t1
LEFT JOIN [dbo].[table2] t2 ON t1.[t1_ID] = t2.[t2_ID]
WHERE t2.[t2_ID] IS NULL
You can use following query structure :
SELECT t1.name FROM table1 t1 JOIN table2 t2 ON t2.fk_id != t1.id;
table1 :
id
name
1
Amit
2
Sagar
table2 :
id
fk_id
email
1
1
amit#ma.com
Output:
name
Sagar
All the above queries are incredibly slow on big tables. A change of strategy is needed. Here there is the code I used for a DB of mine, you can transliterate changing the fields and table names.
This is the strategy: you create two implicit temporary tables and make a union of them.
The first temporary table comes from a selection of all the rows of the first original table the fields of which you wanna control that are NOT present in the second original table.
The second implicit temporary table contains all the rows of the two original tables that have a match on identical values of the column/field you wanna control.
The result of the union is a table that has more than one row with the same control field value in case there is a match for that value on the two original tables (one coming from the first select, the second coming from the second select) and just one row with the control column value in case of the value of the first original table not matching any value of the second original table.
You group and count. When the count is 1 there is not match and, finally, you select just the rows with the count equal to 1.
Seems not elegant, but it is orders of magnitude faster than all the above solutions.
IMPORTANT NOTE: enable the INDEX on the columns to be checked.
SELECT name, source, id
FROM
(
SELECT name, "active_ingredients" as source, active_ingredients.id as id
FROM active_ingredients
UNION ALL
SELECT active_ingredients.name as name, "UNII_database" as source, temp_active_ingredients_aliases.id as id
FROM active_ingredients
INNER JOIN temp_active_ingredients_aliases ON temp_active_ingredients_aliases.alias_name = active_ingredients.name
) tbl
GROUP BY name
HAVING count(*) = 1
ORDER BY name
See query:
SELECT * FROM Table1 WHERE
id NOT IN (SELECT
e.id
FROM
Table1 e
INNER JOIN
Table2 s ON e.id = s.id);
Conceptually would be: Fetching the matching records in subquery and then in main query fetching the records which are not in subquery.
First define alias of table like t1 and t2.
After that get record of second table.
After that match that record using where condition:
SELECT name FROM table2 as t2
WHERE NOT EXISTS (SELECT * FROM table1 as t1 WHERE t1.name = t2.name)
I'm going to repost (since I'm not cool enough yet to comment) in the correct answer....in case anyone else thought it needed better explaining.
SELECT temp_table_1.name
FROM original_table_1 temp_table_1
LEFT JOIN original_table_2 temp_table_2 ON temp_table_2.name = temp_table_1.name
WHERE temp_table_2.name IS NULL
And I've seen syntax in FROM needing commas between table names in mySQL but in sqlLite it seemed to prefer the space.
The bottom line is when you use bad variable names it leaves questions. My variables should make more sense. And someone should explain why we need a comma or no comma.
I tried all solutions above but they did not work in my case. The following query worked for me.
SELECT NAME
FROM table_1
WHERE NAME NOT IN
(SELECT a.NAME
FROM table_1 AS a
LEFT JOIN table_2 AS b
ON a.NAME = b.NAME
WHERE any further condition);

SQL query which give unique entry only once in query table

Basically I have 2 tables 1 OR 2 which is showed in below image.
i want to joint these 2 tables but the value column should be reflect only once in first entry only.
I have basic knowledge about SQL but please guide how can i get the required output as per the criteria which mention above.
You can do this with a left join:
select t2.*, t1.value
from table2 t2 left join
table1 t1
on t1.code = t2.code and t2.type = 'A';

Compare two tables and give the output record which does not exist in 1st table

I want an SQL code which should perform the task of data scrubbing.
I have two tables both contain some names I want to compare them and list out only those name which are in table 2 but not in table 1.
Example:
Table 1 = A ,B,C
Table 2 = C,D,E
The result must have D and E?
SELECT t2.name
FROM 2 t2
LEFT JOIN
1 t1 ON t1.name=t2.name
WHERE t1.name IS NULL
select T2.Name
from Table2 as T2
where not exists (select * from Table1 as T1 where T1.Name = T2.Name)
See this article about performance of different implementations of anti-join (for SQL Server).
select t2.name
from t2,t1
where t2.name<>t1.name -- ( or t2.name!=t1.name)
If the DBMS supports it:
select name from table2
minus
select name from table1
A more portable solution could also be:
select name from table2
where name not in (select name from table1)

Clarification on retrieval of Distinct rows based on a column

SQL Server 2008 R2
I have a table - T1 with id, Title, Firstname, postalcode
Second table - T2 with id, Title and PostalCode.
id is the primarykey in T1 and id is corresponding foreign key in T2.
Now i want to list out the Title from T1, Title from T2 and their id's for the matching id between T1 and T2.
BUT THE MAIN thing is only distinct column values of Title and their correspoding tables T1 and T2 along with their id should be displayed.
For example, If a value 'Mr' is found and if second time if it is found, the value shouldnt be listed again.
Hope iam clear. Please advise.
COALESCE() function could be your friend here.
The Example is a little convoluted, but i think i understand the question.
you will like want to use the Distinct key word:
SELECT DISTINCT T1.Title
FROM T1 INNER JOIN T2 ON T1.id = T2.id
UNION ALL
SELECT DISTINCT T2.Title
FROM T1 INNER JOIN T2 ON T1.id = T2.id
This should grab distinct titles from T1 and T2. I hope this is what you were looking for, if not please describe what you are looking for as far as results a little bit more clearly, if you could add a table view that would be ideal.
Thanks,
~Madullah