SQL Query to compare columns in different table - sql

I have TableA and TableB which contains identical columns but they have different records.
How do I find out which "UniqueID" is not in TableA but in TableB?
I have been doing
select tc.uniqueid, td.uniqueid
from tab1c as tc
left join tab2c as td
where tc.uniqueid != td.uniqueid;
but it doesnt seem to be correct.

Use left join:
select tc.uniqueid, td.uniqueid
from tab1c as tc
left join tab2c as td
on tc.uniqueid = td.uniqueid
where td.uniqueid = NULL; --Will get all uid in tab1c and not in tab2c
The same efficient and more readability way is NOT EXISTS:
select tc.uniqueid
from tab1c as tc
WHERE NOT EXISTS (SELECT * FROM tab2c as td
WHERE tc.uniqueid = td.uniqueid)

The below query will find all the unique id`s which is not there in tableA
SELECT UNIQUEID FROM TABLEB WHERE UNIQUEID NOT IN (SELECT DISTINCT UNIQUEID FROM TABLEA);

Maybe not the most efficient way but you can use EXCEPT
SELECT UNIQUEID
FROM tab1c
EXCEPT
SELECT UNIQUEID
FROM tab2c

Related

How to join two tables on multiple columns using OR condition in bigquery SQL

Lets say I have two tables.
First table shown below:
tableA
Second table
tableB
Now I want to write a query That will join the two tables above on either name OR email OR phone.
Something like:
SELECT * FROM tableA
LEFT JOIN tableB
ON
(tableA.name_A = tableB.name_B OR tableA.email_A = tableB.email_B OR tableA.phone_A = tableB.phone_B)
And it should produce a table something like this
If you notice,
John matches rows between tableA and tableB on name.
Ally/allie matches rows between tableA and tableB on email.
Sam/Samual matches rows between tableA and tableB on phone
When I try to do this same query though I receive an
error that says LEFT OUTER JOIN cannot be used without a condition that is an equality of fields from both sides of the join.
I am using BigQuery.
Please help, cheers
Try INNER JOIN
SELECT * FROM tableA
INNER JOIN tableB
ON
(tableA.name_A = tableB.name_B OR tableA.email_A = tableB.email_B OR tableA.phone_A = tableB.phone_B)
or CROSS JOIN:
SELECT * FROM tableA
CROSS JOIN tableB
WHERE
tableA.name_A = tableB.name_B
OR tableA.email_A = tableB.email_B
OR tableA.phone_A = tableB.phone_B
or UNION DISTINCT:
SELECT * FROM tableA
LEFT JOIN tableB
ON tableA.name_A = tableB.name_B
UNION DISTINCT
SELECT * FROM tableA
LEFT JOIN tableB
ON tableA.email_A = tableB.email_B
UNION DISTINCT
SELECT * FROM tableA
LEFT JOIN tableB
ON tableA.phone_A = tableB.phone_B
could you try by using parenthesis
SELECT * FROM tableA
LEFT JOIN tableB
ON
(tableA.name_A = tableB.name_B) OR
(tableA.email_A = tableB.email_B) OR
(tableA.phone_A = tableB.phone_B)

sql subquery from where in

I'm writing something along these lines:
select fielda,fieldb,
(select sum(field1)-sum(field2) as fieldc
from tableb
where fieldid = list_of_ids[i])
from tablea
where fieldid in (list_of_ids);
In the subquery I'd like to use the value from the outer where clause. So if list_of_ids is 123,456,789 the fieldid in the subquery will be 123, the second 456, etc. Is this possible?
You just need to use ta.fieldid instead of list_of_ids[i]
select ta.fielda,ta.fieldb,
(select sum(tb.field1)-sum(tb.field2) as fieldc
from tableb tb
where tb.fieldid = ta.fieldid )
from tablea ta
where ta.fieldid in (list_of_ids);
A subquery is anchored to the individual record in the outer query.
select fielda,fieldb,
(select sum(field1)-sum(field2) as fieldc
from tableb
where tableb.fieldid = tablea.fieldid)
from tablea
where tablea.fieldid in (list_of_ids);
By just using a simple comparison operator to correlate your subquery with your outer query, your subquery will compare against any fieldids found by the outer query as well.
try this code :
select ta.fielda,ta.fieldb,
(select sum(field1)-sum(field2) as fieldc
from tableb tb
where tb.fieldid = ta.fieldid )
from tablea ta
where ta.fieldid in (list_of_ids);

SQL Select where condition : value 1 <> value 2

Need your help to know if possible to select values from a table with the below condition :
Table content : matching between 2 objects
(Id_obj_A; name_obj_A; country_obj_A; Id_obj_B; name_obj_B; country_obj_B)
Select *
from table
Where (only if country_obj_A <> country_obj_B)
Many thanks for your help
Yes. There are a few ways, one is to use NOT EXISTS like this:
select
*
from tableA
where NOT EXISTS (
select NULL
from tableB
where tableB.country_obj_B = tableA.country_obj_A
)
or, using NOT IN
select
*
from tableA
where country_obj_A NOT IN (
select country_obj_B
from tableB
)
or, using a LEFT JOIN then exclude the joined rows:
select
*
from tableA
left join tableB on tableA.country_obj_A = tableB.country_obj_B
where tableB.country_obj_B IS NULL

How to compare two different tables find out the rest of records

I have two different tables, called tableA and tableB, I want to compare these two tables.
The structures as following:
tableA use following query has 511 records
SELECT count(*)
FROM tableA
WHERE [ID_NAME] = 'a06'
tableB use following query has 507 records
SELECT count(*)
FROM tableB
where [FILENAME] like 'a06%' and [TIME] = '201705'
I wanna to compare these two tables use the common column PNO, I use the following query can find these two tables intersection(507 records):
SELECT count(*)
FROM tableA
WHERE PNO IN (SELECT PNO
FROM tableB
WHERE [FILENAME] like 'a06%' and [TIME] = '201705')
Now, what should I do ? I think use left join can find out the rest of 4 records, but I tried many times it still didn't work, please help me.
You can do that in many ways, and using left join is one of them:
SELECT ta.*
FROM tableA ta
LEFT JOIN
tableB tb
ON ta.[PNO] = tb.[PNO] and
ta.[ID_NAME] = 'a06' and
tb.[FILENAME] like 'a06%' and tb.[TIME] = '201705'
WHERE tb.[PNO] is null
Note that the conditions that were previously in your WHERE clauses are now moved in the join condition; that's because the LEFT JOIN will assign NULL values to the rows that aren't matched, but if you filter on some of the fields of the right table this feature gets lost.
Edit
Another option is following the same path you were using to find the intersection, just adding the condition on tableA and changing IN to NOT IN:
SELECT *
FROM tableA
WHERE PNO NOT IN (
SELECT PNO
FROM tableB
WHERE [FILENAME] like 'a06%' and [TIME] = '201705'
) and
[ID_NAME] = 'a06'
Basically You want to do A-B
SELECT *
FROM tableA t1
WHERE t1.PNO Not IN (SELECT PNO
FROM tableB
WHERE [FILENAME] like 'a06%' and [TIME] = '201705')
OR
SELECT *
FROM tableA t1
WHERE t1.PNO EXCEPT
(SELECT *
FROM tableB
WHERE [FILENAME] like 'a06%' and [TIME] = '201705')
Assuming you are on SQL Server 2008 +
SELECT PNO FROM TABLE A
INTO #TEMP_A
EXCEPT
SELECT PNO FROM TABLE B
Will return the PNO that are not in both tables
SELECT *
FROM tableA
WHERE PNO (Select PNO from #TEMP_A)
Will return all rows in table A with the missing PNO.

SQL Delete based on condition in join

It is possible to delete records based on a satisfied condition with a join query?
For instance, I have a linking table joining 3 records. The query I have at the moment deletes records from this table where one of the id's isn't IN() an imploded Php array. I've come to realise that the query should only remove records from this table if the id's don't exist in the array and they belong to a certain other table based on the a link to another table.
For SQL Server, the command is slightly different:
DELETE FROM TableA
FROM TableA LEFT OUTER JOIN TableB ON TableA.Column = TableB.Column
WHERE TableB.Column IS NULL
No, that's not a typo, yes, you do need "FROM TableA" twice. At least, you need the second FROM (the first is optional). The following has the advantage that it works for both SQL Server and MySQL:
DELETE TableA
FROM TableA LEFT OUTER JOIN TableB ON TableA.Column = TableB.Column
WHERE TableB.Column IS NULL
I like to use EXISTS clauses for this:
DELETE FROM TableA
WHERE
<<put your array condition here>>
AND NOT EXISTS
(SELECT 1 FROM TableB Where TableB.ID=TableA.ID)
You can use :
DELETE Based on a Join:
DELETE A
FROM TableA AS A
LEFT OUTER JOIN TableB As B ON A.Id = B.TabaleAId
WHERE B.Column IS NULL
Delete With SubQuery:
DELETE
FROM TableA AS A
Where
A.id not in ( Select B.TabaleAId From Tab;eB As B )
or
DELETE FROM TableA
WHERE Not EXISTS
(
SELECT *
FROM TableB As B
Where B.TableAId = TableA.Id
)
DELETE Using Table Expressions:
With A
As
(
Select TableA.*
FROM TableA AS A
LEFT OUTER JOIN TableB As B ON A.Id = B.TabaleAId
WHERE B.Column IS NULL
)
Delete From A
DELETE FROM TableA
LEFT OUTER JOIN TableB
WHERE TableB.Column IS NULL
Will delete the records in tableA that don't have a corresponding record in TableB. Is that like what you are after?
DELETE FROM a
FROM TableA AS a LEFT OUTER JOIN TableB AS b
on a.CALENDAR_DATE = b.CALENDAR_DATE AND a.ID = b.ID
Where b.ID is null
You can first use the select statement and verify your records that you want to delete and then remove the select statement and add Delete FROM tablename with the above query syntax.
The easiest way to Delete based on join is as follow:
1.Write your query using SELECT statement instead of DELETE statement
SELECT COLUMNS
FROM Table1
INNER JOIN Table2 ON Table1.YYY = Table2.XXX
2.Replace SELECT COLUMNS with DELETE FROM TABLE
DELETE FROM Table1
FROM Table1
INNER JOIN Table2 ON Table1.YYY = Table2.XXX
Note that we need to specify FROM twice, one for DELETE part and one for JOIN part.
delete from TableA
where id in
(
select id from TableA
except select id from TableB
)
Which means "delete from tableA where id in table a but not in table b)
Otherwise a Merge statement might help you (when matched/not matched delete etc)
http://technet.microsoft.com/en-us/library/bb510625.aspx