How to compare data any field of two table in SQL Server? - sql-server

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

Related

SQL multi-part identifier can't be bound in SELECT

Is it possible to add a case using a column from other tables than first in the from section?
I can't use anything like C.code or Y.anything in the SELECT part:
SELECT
fromTableA, fromTableA, fromTableA,
CASE
WHEN fromTableA = anyValue THEN 'is_ok'
WHEN B.fromTableB = anyValue THEN 'couldnt.be.bound'
WHEN fromTableB = anyValue THEN 'invalid.column.name'
END AS X
FROM
(SELECT fromTableA,
SUM(fromTableA),
CASE WHEN A.fromTableA = 'anything' THEN 'still ok'
WHEN C.fromTableC = 'allowed' THEN 'no problem'
FROM tableA A
JOIN tableB B ON A.id = B.id
JOIN tableC C ON C.id = B.id
Having SUM(fromTableA) > 0
) AS Y
Edit: What I need is to use columns from table B or C in the outer Select ( I just can't remove the inner select because i would lost cases and aggregation operations there are in the inner select).
The following should be all you need, a derived table here doesn't accomplish anything.
select A.Cols...,
case
when A.col1 = anyValue then 'is_ok'
when B.Col1 = anyValue then 'couldnt.be.bound'
when B.Col2 = anyValue then 'invalid.column.name'
end as X
from tableA A
join tableB B on A.id = B.id
join tableC C on C.id = B.id;

Use CASE or REPLACE for my conditional Query

I have 2 tables on which join is there.
for second table TableB i am fetching both id and post.
SELECT a.id,
a.NAME,
b.id,
b.post
FROM tableA a
INNER JOIN tableB b
ON a.bid = b.id
But in one case b.id=3 i have post ='manager' but i have to show post='associate manager'. i cannot change table values but only query.
I am currently using replace .
SELECT a.id,
a.NAME,
b.id,
replace(b.post, 'manager', 'associate manager')
FROM tableA a
INNER JOIN tableB b
ON a.bid = b.id
Should i switch to case or this is correct.
Regards,
Use Case Statement
SELECT a.id,
a.NAME,
b.id,
CASE
WHEN b.id = 3 THEN 'associate manager'
ELSE post
END
FROM tableA a
INNER JOIN tableB b
ON a.bid = b.id

Need Unique Value from table

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.

SQL: How do I check for records in one table that aren't in another?

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

searching for records using Full text search across multiple tables

SELECT A.a, B.b, akt.[Rank] + bkt.[Rank] /2 AS [Rank]
FROM B b
INNER JOIN Publication a ON a.Id = b.Id
INNER JOIN FREETEXTTABLE(A, a, 'search text') akt ON a.Id = akt.[Key]
INNER JOIN FREETEXTTABLE(B, b, 'search text') bkt ON b.Id = bkt.[Key]
ORDER BY [Rank] DESC
UNION
SELECT A.a, null as B.b, akt.[Rank] as [Rank]
FROM A a
INNER JOIN FREETEXTTABLE(A, a, 'search text') akt ON a.Id = akt.[Key]
UNION
SELECT null as A.a, B.b, bkt.[Rank] as [Rank]
FROM B b
INNER JOIN FREETEXTTABLE(A, a, 'search text') akt ON a.Id = akt.[Key]
The above query is for searching records (using rankings) across two tables.
The first query : Only those records will be displayed where the search text is in both the columns of the two tables.
Second query : Only those records where searchtext is only in column a of table A
Third query : Only those records where searchtext is only in column b of table B
My question is: If I have to search across 4 or 5 tables, the number of UNIONS will increase like crazy. It will be too complicated and slow as well.
So, Is there any other method which could reduce these UNIONS?
I tried Views, but they cannot be full text indexed.
Simply use full join
SELECT A.a, B.b, "Use case for calculating rank"
FROM B b
FULL JOIN A a ON b.Id = a.Id
WHERE
a.[columnname] = 'search text' OR
b.[columnname] = 'search text'
Check http://codesnout.com/SQLSample/SQL-FULL-JOIN.php
SELECT b.FK_Publication_ID, b.PageNumber as PageNumber, b.SearchText as SearchText, a.Title as Title ,
TitleSearch.[Rank] + PubSearch.[Rank] * 10000
AS [Rank]
FROM PublicationSearch
INNER JOIN Publication a ON b.FK_Publication_Id = a.Id
INNER JOIN FREETEXTTABLE(PublicationSearch, SearchText, "searchtext") PubSearch ON b.Id = PubSearch.[Key]
INNER JOIN FREETEXTTABLE(Publication, Title, "searchtext") TitleSearch ON a.Id = TitleSearch.[Key]
WHERE b.FK_ContentType_Id IN (SELECT * FROM UF_CSVToTable(#Options))
UNION
SELECT a.Id, null as PageNumber, null as Searchtext, a.Title as Title, TitleSearch.[Rank] * 100 AS [Rank]
FROM Publication a
INNER JOIN FREETEXTTABLE(Publication,Title, "searchtext") TitleSearch ON a.Id = TitleSearch.[Key]
UNION
SELECT b.FK_Publication_ID, b.PageNumber as PageNumber, b.SearchText as SearchText, null as Title,
PubSearch.[Rank]
AS [Rank]
FROM PublicationSearch b
INNER JOIN FREETEXTTABLE(PublicationSearch, SearchText, "searchtext") PubSearch ON b.Id = PubSearch.[Key]
ORDER BY [Rank] DESC
The above is using UNION
Below is as you suggested
SELECT b.FK_Publication_ID, b.PageNumber as PageNumber, b.SearchText as SearchText, a.Title as Title as ContentType ,
TitleSearch.[Rank] * 100 (Ranking, dont know how to do it here)
AS [Rank]
FROM PublicationSearch b
INNER JOIN Publication a ON b.FK_Publication_Id = a.Id
JOIN FREETEXTTABLE(PublicationSearch, SearchText, "searchtext")PubSearch ON b.Id = PubSearch.[Key]
FULL JOIN FREETEXTTABLE(Publication, Title, "searchtext")TitleSearch ON a.Id = TitleSearch.[Key]
order by [RANK] desc
Heres, the exact script. Using Full Join, I get the records from BOTH table AND records from only PublicationSearch table BUT NOT only from Publication table
Also, the records found in both tables should be ranked higher, then records from only Publication table AND THEN records from PublicationSerach table
Thanks..

Resources