(SQL) How to check if a value is in another table? - sql

I'm not very good with SQL so I apologise.
I want to be able to go through each row on Table A and check if a specific value exists in an entire column in Table B.
I want to see all rows from table A where value is NOT in specific column in table B.
I hope that makes sense.

You can use not exists. Your question is a bit theorical, the but the logic would be:
select a.*
from tablea a
where not exists (select 1 from tableb b where b.col1 = a.col1)
Where values in tabla(col1) should correspond to values in tableb(col1).

It sounds like not exists:
select a.*
from a
where not exists (select 1 from b where b.col = a.col);

Related

duplicate query result when join table

I face issue about duplicate data when join table, here my sample data table I have
-- Table A
I want to join with
-- Table B
this my query notation for join both table,
select a.trans_id, name
from tableA a
inner join tableB b
on a.ID_Trans = b.trans_id
and this the result, why I get the duplicating data which should show only two lines of data, please help me to solve this case.
Firstly, as you have been told multiple times in the comments, this is working exactly as you have written, and (more importantly) as intended. You have 2 rows in tableA and those 2 rows match 2 rows in your table tableB according to the ON clause. This means that each join operation, for the each of the rows in tableA, results in 2 rows as well; thus 4 rows (2 * 2 = 4).
Considering that your table, TableA only has one column then it seems that you should be cleaning up that data and deleting the duplicates. There are plenty of examples on how to do that already (example).
Perhaps the column you show us in TableA is one many, and thus instead you have a denormalisation issue, and instead there should be another table with the details of Id_trans and a PRIMARY KEY or UNIQUE CONSTRAINT/INDEX on it. Then you would join fron that table to TableB.
Finally, what you might be after is an EXISTS, which would look like this:
SELECT B.trans_id, B.[name]
FROM dbo.TableB B
WHERE EXISTS(SELECT 1
FROM dbo.TableA A
WHERE A.ID_Trans = B.trans_id); --Odd that it's called ID_Trans in one table, and Trans_ID in another
As the comments mentioned your query does exactly what you asked it to do but I think you wanted something like:
select a.trans_id, a.name, b.name
from tableA a
inner join tableB b on a.trans_id = b.trans_id
group by a.trans_id, a.name, b.name
Since there are two rows in both table with same ID join will make them four. You can use distinct to remove duplicates:
select distinct a.trans_id, name
from tableA a
inner join tableB b
on a.id_trans = b.trans_id
But I would suggest to use exists:
select trans_id, name
from tableB b
exists (select 1 from tableA a where a.trans_id=b.trans_id)

How do I delete all rows in a table which have a null foreign key reference?

I have two tables, A and B. A has a column B_Id which references the Id column of table B.
There are a number of rows in table A that have a value for B_Id, but that value does not exist anywhere in the list of Ids of table B.
I want to delete all of these particular rows.
I've tried
select * from A left join B on A.B_Id = B.Id where B.Id = null
But this doesn't select anything at all. How can I change the select to retrieve the rows I want?
NOT EXISTS comes to mind:
select a.*
from a
where not exists (select 1 from b where b.id = a.b_id);
You can easily incorporate this into a delete if you want to remove the rows:
delete from a
where not exists (select 1 from b where b.id = a.b_id);
BUT . . . you should really fix the problem moving forward by putting in a proper constraints. You seem to want a NOT NULL constraint and a FOREIGN KEY constraint.
You need where b.id is null rather than where b.id = null. In SQL, nothing is equal to null (nor different than null): to compare against null, you need special construct is [not] null.
I think that this is simpler expressed with not exists:
select a.*
from a
where not exists (select 1 from b where b.id = a.b_id)
If you wanted a delete statement:
delete from a
where not exists (select 1 from b where b.id = a.b_id)
You need to use the IS operator, like
select * from A left join B on A.B_Id = B.Id where B.Id is null
the reason is that null is unkown and the language isn't certain whether something is equal to it or not. You can also do it via not exists as Gordon Linoff has already pointed out.
Whatever you try, make sure that you make a full backup of your table.
If B_Id is already a foreign key and foreign key checking is enabled for your database, then you can safely assume that every record that has no pair in B has a B_Id of null in A, which renders the join and checking for existence unnecessary.
You can select the data you want to delete with
SELECT * FROM A
WHERE B_ID NOT IN (SELECT ID FROM B);
To delete these rows just use this
DELETE FROM A
WHERE B_ID NOT IN (SELECT ID FROM B);

Find deleted rows: Not EXISTS vs Not IN

In my case, I have two table with same structure: TableA & TableB, and what I was trying to do is to find if there is any records only exists in A but not B.
My script was
SELECT * FROM TableA
WHERE NOT EXISTS (
SELECT * FROM TableB
)
While there is 2 records which only exists in A but not B, this script returns nothing. Then I changed into following:
SELECT ID FROM TableA
WHERE ID NOT IN (
SELECT ID FROM TableB
)
This script works successfully and return the 2 records' ID.
My question is: Is this behavior normal? What is the mechanism behind NOT EXISTS and NOT IN?
I have read some other posts comparing NOT EXISTS and NOT IN, and most people suggest using NOT EXISTS in 99.9% scenarios, is this case fall into that 0.1% which NOT EXISTS is not applicable? (I believed it's due to my wrongly usage though, please correct me if that's the case)
If you want to look at all the values in the rows, then use EXCEPT:
SELECT *
FROM TableA
EXCEPT
SELECT *
FROM TableB;
If you want to use NOT EXISTS correctly, then you need a correlation clause:
SELECT a.*
FROM TableA a
WHERE NOT EXISTS (SELECT 1 FROM TableB b WHERE b.id = a.id);
I strongly recommend using NOT EXISTS over NOT IN with a subquery. NOT IN will return no rows at all if b.id is ever NULL. That is usually not what is intended. NOT EXISTS matches the expected semantics.
You need to be careful with the NOT IN expression.
The A NOT IN(B,C,D) expression basically means (A<>B AND A<>C AND A<>D). If any of the values are NULL the whole expression will become NULL.
So, applicable to your example the correct NOT IN expression should be (unless the ID is not nullable column):
SELECT ID FROM TableA
WHERE ID NOT IN (
SELECT ID FROM TableB WHERE ID IS NOT NULL
)

Include table name in column from select wildcard sql

Is it possible to include table name in the returned column if I use wildcard to select all columns from tables?
To explain it further. Suppose I want to join two tables and both tables have the column name “name” and many other columns. I want to use wildcard to select all columns and not explicitly specifying each column name in the select.
Select *
From
TableA a,
TableB b
Where
a.id = b.id
Instead of seeing two column with same name "name", could I write a sql to return one column name as "a.name" (or TableA.name) and one as "b.name"(or TableB.name) without explicitly putting the column name in select?
I would prefer a solution for mssql but other database could be a reference too.
Thanks!
You can use select a.*, ' ', b.* from T1 a, T2 b to make it more visible where columns from T1 end and columns from T2 begin.
You are basically joining two tables on the ID field, so you will only see one column labeled "ID", not two, because you are asking to see only those records where the ID is the same in table a and table b: they share the same id.
Try ...
SELECT 'TableA' AS 'Table', A.* FROM TableA A
WHERE A.id IN (SELECT id FROM TableB)
UNION
SELECT 'TableB' AS 'Table', B.* FROM TableB B
WHERE B.id IN (SELECT id FROM TableA)
ORDER BY id, [Table]

Sql Join Query using MS Access

Hello I Have a problem in getting rows from one table after comparing both. Detail of Both Table are as follows:-
I am using Ms Access database.
TableA is having a data of numeric type (Field Name is A it is primary key)
----------
Field A
==========
1
2
3
4
5
Table B is having data of numeric type ( Field Name is A it is foreign key)
--------
Field A
========
2
4
Now I am using below query which is this
select a.a
from a a
, b b
where a.a <> b.b
I want to show all the data from Table A which is not equal to Table B. But the above query is not working as I described.
Can you help me in this regard.
Regards,
Fawad Munir
In an attempt at clarity, I've used upper case for tables and lower case for fields:
Select A.a
FROM A LEFT OUTER JOIN B ON A.a=B.b
WHERE B.b is null
This will show all the records in A that are not in B (I assume that's what you want).
Read up on Access outer joins. In the query designer you double click the join and select something like "all records from table a and only the matching records in table b".
In your question you said that the name of the field in table B is 'A'. Given that, I'd say that your query should be something like
select a.a
from a, b
where a.a <> b.a
But I'm not sure this will do what you want. I think you're trying to find rows in table A which do not have a matching row in table B, in which case you might try
SELECT A.A
FROM A
LEFT OUTER JOIN B
ON (B.A = A.A)
WHERE B.A IS NULL
Try that and see if it does what you want.
Share and enjoy.
I don't know exactly if Access would accept the syntax, but here how I would do in SQL Server.
select a.a
from TableA a
where a.a NOT IN (
select b.a
from TableB b
)
or even as above-mentioned:
select a.a
from TableA a
left outer join TableB b on b.a = a.a
where b.a IS NULL
Its not entirely clear what you are trying to achieve, but its sounds like you are attempting to solve the common problem of finding rows in Table A missing associated data in Table B. If this is the case, it appears you misunderstand the semantics of the join you tried. In which case, you have 2 problems, because the understanding the the JOIN operation is critical to working with relational databases.
In relation to the first problem, please research how to express a subquery using the IN operator. Something like
... WHERE a NOT IN (SELECT a from b)
In relation to the second problem, try your query without the WHERE restriction, and see what is returned. Once you understand what the join is doing, you will see why applying a WHERE restriction to it will not solve your problem.
If I understand you correctly, you want to see every row in A for which column a contains a value that cannot be found in any column b value of B. You can get this data in several ways.
I think using NOT IN is the clearest, personally:
SELECT * FROM tableA WHERE columnA NOT IN
(SELECT columnB FROM tableB WHERE columnB IS NOT NULL)
Many people prefer a filtered JOIN:
SELECT tableA.* FROM tableA LEFT OUTER JOIN tableB
ON tableA.columnA = tableB.columnB WHERE tableB.columnB IS NULL
There is a NOT EXISTS variant as well:
SELECT * FROM tableA WHERE columnA NOT EXISTS
(SELECT * FROM tableB WHERE columnB = tableA.columnA)