How to find records that exist in all 4 tables? SQL Server 2008 - sql

I have to migrate records from one system to another. There is 4 different tables. First table contains all information about each user. Each row has unique ID that is primary key. So I need to grab primary key from table one and find matching record in other 3 tables. Those tables have foreign key that we should use to match users. Here is example:
SELECT *
FROM Users AS ur
WHERE EXISTS(
SELECT *
FROM TableA AS a
WHERE ur.ur_id = a.a_urid
)
//Maybe second option can be to use INNER JOIN
SELECT *
FROM Users AS ur
INNER JOIN TableA AS a
ON ur.ur_id = a.a_urid
INNER JOIN TableB AS b
ON ur.ur_id = b.b_urid
INNER JOIN TableC AS c
ON ur.ur_id = c.c_urid
Query above will return matching records only for Users and Table A. I'm wondering if I can match all records from Users table that have matching user ID in table A, B and C. How that can be achieved in SQL Server 2008? Or I would need to add/import each table individually? If anyone can help with this task please let me know. Thank you!

You can use intersect:
select u.id
from users u
intersect
select a.a_urid
from a
intersect
select b.b_urid
from b
intersect
select c.c_urid
from c;
Another way is to use exists:
SELECT ur.*
FROM Users ur
WHERE EXISTS (SELECT 1 FROM TableA AS a WHERE ur.ur_id = a.a_urid) AND
EXISTS (SELECT 1 FROM TableB AS b WHERE ur.ur_id = b.b_urid) AND
EXISTS (SELECT 1 FROM TableC AS c WHERE ur.ur_id = c.c_urid) ;
Using a JOIN, you have to be careful. The result set might contain duplicates. And removing the duplicates could be very expensive.

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)

SQL Get rows that doesn't appear in another table

I have this SQL problem: I have tables A and B. Table A has columns id and name, Table B amount and id which is a foreign key to table A.id.
I need to return all table A rows that don't have their id stored in table B. Any ideas?
So the complete opposite is:
SELECT *
FROM a
LEFT OUTER JOIN b ON a.id = b.id;
Here row what I need is left out of result
Just add a where clause:
SELECT a.*
FROM a LEFT OUTER JOIN
b
ON a.id = b.id
WHERE b.id IS NULL;
You can also use NOT EXISTS:
select a.*
from a
where not exists (select 1 from b where b.id = a.id);
In most databases, the two methods typically have similar performance.

Delete records from Postgresql

I need to delete records from one table based on inner join condition on other two tables, however query runs for ages.
DELETE FROM public.blacklist WHERE subject_id NOT IN(
SELECT DISTINCT a.id FROM public.subject a
INNER JOIN stg.blacklist_init b ON a.subject_id=b.customer_code);
Any ideas how to achieve this?
Thank you.
You can use NOT EXISTS instead of NOT IN, and I think you don't need a DISTINCT
DELETE FROM public.blacklist bl
WHERE NOT EXISTS (
SELECT 0
FROM public.subject a
INNER JOIN stg.blacklist_init b
ON a.subject_id=b.customer_code
WHERE a.id = bl.subject_id
);

Table without ID's in other Table

In my SQL Server 2008 I've got two tables.
Table: All kinds of Users with unique ID's
Table: Blacklisted Users with ID's
Now I'd like to get all Users that are not on the blacklist.
Just doesn't work like I want it to
SELECT A.ID, B.ID FROM Users AS A INNER JOIN Blacklist AS B ON
A.ID != B.ID
Can someone help?
If you expect it to not to be in Blacklist, you won't have any data to select from blacklist in select statement
SELECT A.*
FROM Users A
Where A.ID NOT IN (Select Id From Blacklist )
If you wish, read more about Subqueries with NOT IN
What you want is an anti-join, something like this:
SELECT A.ID, B.ID FROM Users AS A LEFT JOIN Blacklist AS B ON
A.ID = B.ID
WHERE B.ID IS NULL
That is, we perform the join, and then in the WHERE clause we apply a filter which eliminates rows where the join was successful.
Your original query doesn't work (assuming that there is more than one row in Blacklist and that they have different ID values) because, for any ID value in A, we can find a row in B which doesn't match it - even if there's also a row which does match it.
SELECT *
From Users
WHERE ID NOT IN (SELECT ID From BlackListedUsers)
That should select all that are not in the blacklist table.

Select returns the same row multiple times

I have the following problem:
In DB, I have two tables. The value from one column in the first table can appear in two different columns in the second one.
So, the configuration is as follows:
TABLE_A: Column Print_group
TABLE _B: Columns Print_digital and Print_offset
The value from the different rows and Print_group column of the Table_A can appear in one row of the Table_B but in different column.
I have the following query:
SELECT DISTINCT * FROM Table_A
INNER JOIN B ON (Table_A. Print_digital = Table_B.Print_group OR
Table_A.Print_offset = Table_B.Print_group)
The problem is that this query returns the same row from the Table_A two times.
What I am doing wrong? What is the right query?
Thank you for your help
If I'm understanding your question correctly, you just need to clarify your fields to come from Table_A:
SELECT DISTINCT A.*
FROM Table_A A
INNER JOIN B ON A.Print_digital = B.Print_group
OR A.Print_offset = B.Print_group
EDIT:
Given your comments, looks like you just need SELECT DISTINCT B.*
SELECT DISTINCT B.*
FROM Table_A A
INNER JOIN B ON A.Print_digital = B.Print_group
OR A.Print_offset = B.Print_group
I've still another question... first,to be clear, the right query version is
SELECT DISTINCT A.*
FROM Table_A A
INNER JOIN B ON A.Print_digital = B.Print_group
OR A.Print_offset = B.Print_group.
If I want it returns also one column from the B table it again returns duplicate rows. My query (the bad one) is the following one:
SELECT DISTINCT A.*, B.Id
FROM Table_A A
INNER JOIN B ON A.Print_digital = B.Print_group
OR A.Print_offset = B.Print_group