I have two tables:
Table A
ID Name
1 abc
2 xyz
Table B
ID Name
1 abc
2 xyz
3 mno
I need the distinct value form above two table, I mean i want only ID 3 Name mno from Table B (as it is unique from two table)
Please let me know how I can get this value.
Thanks,
Ajay
This query will get you the rows from B that don't exist in A:
SELECT b.* FROM TableB b
OUTER JOIN TableA a ON a.ID = b.ID AND a.Name = b.Name
WHERE a.ID IS NULL
you could then do the adverse and use a UNION ALL to get it both ways:
SELECT a.* FROM TableA a
OUTER JOIN TableB b ON b.ID = a.ID AND b.Name = a.Name
WHERE b.ID IS NULL
UNION ALL
SELECT b.* FROM TableB b
OUTER JOIN TableA a ON a.ID = b.ID AND a.Name = b.Name
WHERE a.ID IS NULL
Another way of achieving it would be:
;WITH MatchingRows AS (
SELECT a.ID FROM TableA a
JOIN TableB b ON b.ID = a.ID AND b.Name = a.Name
)
SELECT * FROM TableA
WHERE ID NOT IN (SELECT m.ID FROM MatchingRows m)
UNION ALL
SELECT * FROM TableB
WHERE ID NOT IN (SELECT m.ID FROM MatchingRows m)
I'm not sure if that performs better or not - it's just something I thought of. If I'm not mistaken this will actually run the WITH query twice (see the answer to this question) because it's being used twice - so there may be some performance implications with this approach.
The EXCEPT operator may work for you. Here is an example using your data.
CREATE TABLE TableA (id int, name varchar(50))
INSERT INTO TableA VALUES (1, 'abc'),(2,'xyz')
CREATE TABLE TableB (id int, name varchar(50))
INSERT INTO TableB VALUES (1, 'abc'),(2,'xyz'),(3,'mno')
SELECT * FROM TableB
EXCEPT
SELECT * FROM TableA
Be warned though it acts like UNION. It's only going to exclude rows where there is an exact match on all columns.
Related
I have two tables with same columns.
Table A have ID, Name, Des, Status and
Table B have ID, Name, Des, Status.
I want to compare data any field of Table B with Table A, except column ID because same.
As same picture above, when FETCH data of Table B, detect data of ID ID001 and ID003 not same, idea of my mind same
IF (SELECT COUNT (SELECT * FROM TABLE A RIGHT JOIN TABLE B ON A.ID = B.ID) != 0)
BEGIN
PRINT 'BLAH BLAH, NOT SAME'
END
If you have idea or solution, share for me, Thank you so much.
You can use CHECKSUM or BINARY_CHECKSUM:
SELECT a.*, b.*
FROM TableA a INNER JOIN TableB b ON b.ID = a.ID
WHERE CHECKSUM(b.Name, b.Des, b.Status) <> CHECKSUM(a.Name, a.Des, a.Status)
See also this link. It should be faster then multiple OR conditions.
IF (SELECT COUNT(*)
FROM TableA a INNER JOIN TableB b ON b.ID = a.ID
WHERE BINARY_CHECKSUM(b.Name, b.Des, b.Status)
<> BINARY_CHECKSUM(a.Name, a.Des, a.Status)
>0
PRINT 'Not the same.'
Since it is not too much clear how do you want to show your differences, this is one approach:
SELECT A.ID,
(CASE WHEN A.Name <> B.Name THEN 'Diff Name' ELSE '') NameCompare,
(CASE WHEN A.Des <> B.Des THEN 'Diff Des' ELSE '') DESCompare,
(CASE WHEN A.Status <> B.Status THEN 'Diff Status' ELSE '') StatusCompare
FROM A
INNER JOIN B
ON A.ID = B.ID
This is a simple join
To get all different rows, you can say:
select a.*, b.*
from TableA a inner join TableB b on b.ID = a.ID
where b.Name <> a.Name or b.Des <> a.Des or b.Status <> a.Status
Suppose I have table A and B, table A contains 30 rows of ID and table B contains 60 rows of ID, I want to insert B.ID into A.ID by using where not exist. Table B ID will be inserted into Table A if the B.ID does not exist in Table A.
INSERT INTO A(
ID)
SELECT ID
FROM B
WHERE NOT EXISTS (Select ID From A WHERE A.ID = B.ID)
I think there are some problems in my subqueries. Please advice me on how to correct this.
Suppose A.ID is in NVARCHAR(200) type and B.ID is in FLOAT type.
INSERT INTO A(
ID)
SELECT Cast(Cast(ID as Float)as Nvarchar)
FROM B
WHERE NOT EXISTS (Select ID From A WHERE A.ID = B.ID)
But there is still error: Error converting data type nvarchar to float.
TIA!
Use join instead of sub query for better performance
INSERT INTO A(ID)
SELECT CAST(B.ID AS nvarchar(200))
FROM A RIGHT JOIN B ON A.ID = CAST(B.ID AS NVARCHAR(200)) WHERE A.ID IS NULL
INSERT INTO A(
ID)
SELECT CAST(B.ID AS nvarchar(200))
FROM B
WHERE NOT EXISTS (SELECT 1 FROM A WHERE A.ID = CAST(B.ID AS nvarchar(200)))
But I would like you to take a look at Unique Constraints and Check Constraints.
The DB I'm working with has the following 2 tables:
tblGroup
GroupId
GroupName
OtherGroupField, etc.
tblParts
PartId
PartNumber
GroupId
Price
OtherPartField, etc.
In my query I'd like to get the GroupId(s) which aren't in tblParts for a specified PartNumber
You can use the NOT IN predicate like this:
SELECT *
FROM tblGroups
WHERE GroupId NOT IN
(
SELECT GroupId
FROM tblParts
WHERE PartNumber = 'Some number'
AND GroupId IS NOT NULL
)
I would use an EXISTS with a join, rather than IN for better performance.
SELECT *
FROM tblGroups G
WHERE 1=1
And Not Exists
(
SELECT 1
FROM tblParts P
WHERE 1=1
And G.GroupId = P.GroupId
And PartNumber = 'PartNumberGoesHere'
)
My preference is EXCEPT
select GroupId from tblGroup
except
select GroupId from tblParts where PartNumber = 22
Its a little cleaner syntactically than outer joins even with a single item, but you can also use it to compare whole rows, e.g. looking for all rows of {A,B,C} that exist in table1 but not table2:
select A, B, C from table1
except
select A, B, C from table2
try with this
SELECT *
FROM tblGroups G
LEFT OUTER JOIN tblParts P ON P.GroupId=G.GroupId
WHERE P.PartId IS NULL
I want to find records that are in one table but not in another. Except the records aren't formed the same. So I'm wanting to determine the columns I want to use to compare against. I thought I had it worked out with the following code, but it doesn't seem to be working (Returns zero records)...
SELECT A.Name, A.Position, A.[Year]
FROM TABLE A
WHERE NOT EXISTS (
SELECT B.Name, B.Position, B.[Year]
FROM TABLE B
)
Or should I be doing this with some kind of join? Thanks...
You're missing the WHERE clause to compare the two tables to one another:
SELECT A.Name, A.Position, A.[Year]
FROM TABLE A
WHERE NOT EXISTS (
SELECT B.Name, B.Position, B.[Year]
FROM TABLE B
WHERE B.Name = A.Name AND B.Position = A.Position AND B.[Year] = A.[Year]
)
Assuming you want use all three columns to do the comparison you can use an anti-join.
SELECT A.Name, A.Position, A.[Year]
FROM TABLE_A A
LEFT JOIN TABLE_B B
ON a.name = b.name
and a.position = b.position
and a.[Year] = b.[Year]
WHERE
b.name is null
You can use an left outer join on table b with a where clause looking for null values.
I am assuming that everything in the first query comes from table A and everything in the second comes from table B
Select A.Name, A.Position, A.[Year]
from A
Left Join B on A.Name = B.Name and A.Position = B.Position and A.[Year] = B.[Year]
where B.Name is Null
I need a query that returns rows from table A if value X in table A is not the same as the sum of value Y from corresponding row(s) in table B. The issue is that there may or may not be rows in table B that correspond to the rows in table A, but if there no rows in table B, then the rows from table A should still be returned (because there is not a matching value in table B.) So it is like a LEFT OUTER join scenario, but the extra complication of having a comparison as an additional selection criteria.
I have a query that does the opposite, ie. returns rows if the value in table A is the same as the value of row(s) in table B, but sadly this isn't what I need!
SELECT TableA.id, TableA.bdate
FROM TableA
LEFT JOIN TableB ON TableB.ID = TableA.id
WHERE TableA.select_field = 408214
AND TableA.planned_volume =
(select sum(actual_volume)
from
TableB
where TableB.id = TableA.id)
ORDER BY TableA.id
Any help greatly appreciated.
How about something like this:
SELECT TableA.Id, TableA.bdate
FROM TableA
LEFT JOIN
(
SELECT Id, SUM(actual_volume) AS b_volume
FROM TableB
GROUP BY Id
) AS TableBGrouping
ON TableBGrouping.Id= TableA.Id AND TableA.planned_volume <> b_volume
ORDER BY TableA.Id
WITH TotalVolumes
AS
(
SELECT id, SUM(actual_volume) AS total_volume
FROM TableB
GROUP
BY id
)
SELECT id, bdate, planned_volume
FROM TableA
EXCEPT
SELECT A.id, A.bdate, T.total_volume
FROM TableA AS A
JOIN TotalVolumes AS T
ON A.id = T.id;
SELECT TableA.id, TableA.bdate
FROM TableA
LEFT JOIN TableB ON TableB.ID = TableA.id
AND TableA.planned_volume <>
(select sum(actual_volume)
from
TableB
where TableB.id = TableA.id)
ORDER BY TableA.id