SQL Server compare data - sql

I am attempting to compare 2 columns in one SQL Table. Column1 has 012-0000430-001 and Column2 has 0120000430001 both nvarchar data types. I would like to run a compare to make sure both tables match.
select Column1,substring(Column2,1,3)
+ substring(Column2,5,7)
+substring(Column2,13,3)
from Table1
This query gives me the data but what could I do next to see which data matches and which does not. I would eventually like to create a trigger that find the mismatch and then correct it.
Thanks in advance!

If you want to compare them, how about something like this?
select column1, column2,
(case when column2 = replace(column1, '-', '') then 'same'
else 'diff'
end)
from table1;

select CASE WHEN replace(Column1,'-','')= Column2 then
'Equals' else 'Not Equals' end from Table_Name

Related

Compare two fields in SQL to see if there are values in common

this is my first post so hopefully you great people out there will be able to help me please.
I have a data table with two columns of people's names. The names are pipe delimited. I want to identify whether or not there are any names in common within those two columns with a True/False/Unknown output field appended for each row. The result is 'Unknown' if one field is blank.
I am looking for an output like attached based on the two input columns.
Is this possible to do in TSQL (we're running SQL database on Azure)? Any help is much appreciated. Thanks.
If you are running SQL Server 2016 or higher, one option uses string_split():
select
field1,
field2
case
when field1 is null or field2 is null
then 'Unknown'
when exists (select 1 from string_split(field1, '|') where field2 like '%' + value + '%' )
then 'True'
else 'False'
end as result
from mytable
That said, your first effort should go into fixing your data model. Storing delimited lists in a table column basically defeats the purpose of a relational database, and should always be avoided. Each value should appear on a separate row.
Using a split() function, I would recommend apply:
select t.*,
(case when names_in_common > 0 then 'true'
when field1 is null or field2 is null then 'unknown'
else 'false'
end) as flag
from t outer apply
(select count(*) as names_in_common
from string_split(field1, '|') s1 join
string_split(field2, '|') s2
on s1.value = s2.value
) n

SQL select not viewing correct data

I have earlier been using MySQL and there I could get the correct response with this select query.
SELECT *
FROM TABLE
WHERE COLUMN1 NOT IN ('Done', 'Closed')
AND COLUMN2 IN ('Dude1', 'Dude2', 'Dude3')
Now we have changed db to oracle and there it leaves out if COLUMN1 have no value in it. In another words, it's null/empty.
I have tried what I believe would be the correct way to make the query but it behaves not as I was hoping. Maybe someone have a solution that I could retrieve same information as in MySQL.
Last attempt I ended up with this query
SELECT *
FROM TABLE
WHERE COLUMN1 NOT IN ('Done', 'Closed')
OR COLUMN1 IS NULL
AND COLUMN2 IN ('Dude1', 'Dude2', 'Dude3')
When I run this query I get all that have null/empty as value in COLUMN1 but I also get Dude6 in COLUMN2 from the reply... and I can't figure out how I could do it any other way..
If I remove
OR Column1 IS NULL
I won't get the mysterious Dude6 as responses but I also won't get the rows where column1 is empty/null and with Dude1 in it for example..
You just need parentheses around your OR expression:
SELECT *
FROM TABLE
WHERE
(COLUMN1 NOT IN ('Done','Closed') OR COLUMN1 IS NULL)
AND COLUMN2 IN ('Dude1','Dude2','Dude3')

use 'case when' after in function

I need to use case when to generate the value range for in function (in DB2).
for example, in below code, I want the columnB in (5,6)
select columnA from tableName where columnB in (
(case
when #variable=1 then '4' // specific number
when #variable=2 then '5' //specific number
when #variable=3 then '7,10' // a value range
end)
)
but tried several times and other similar solutions, never got the expected result
how to do this?
Firstly, In function does not read multiple values inside Case statement. The comma must be after every single value in the range.
Second, you can mention a valid condition in your Question, rather than just 1=1. It's always true so, doesn't make sense.
Example:
1) output of below query gives in (5, 6)
select columnA from tableName where columnB in ((case when #variable=1 then 5 end), 6);
2) this gives only records of columnB = 5, let say the second condition is false.
select columnA from tableName where columnB in ((case when #variable=1 then 5 end), (case when #variable=2 then 6 end));
try Something like this
select columnA from tableName
where columnB in (
select * from table(values 4) tmp(NewCol)
where #variable=1
union all
select * from table(values 5) tmp(NewCol)
where #variable=2
union all
select * from table(values 7, 10) tmp(NewCol)
where #variable=3
)
You cannot have string as value range unless you convert it into rowset. I'm not sure how to do this in DB2, but I have something that should work, since according to documentation, DB2 does have unnest(). There are of course other ways to create rowsets.
SELECT columnA
FROM unnest(array[2,6,8,10], array[7,5,6,28]) --create "temp table" for example purposes
WITH ORDINALITY AS a(columnA, columnB) --alias columns from temp table
WHERE
CASE WHEN true THEN --switch true to some other condition
columnB IN(SELECT * FROM unnest(array[5,6])) --unnest(array[]) will create rowset with 2 rows, each having one column holding integer value
END;
You might need to drop alias from AS a(columnA, columnB) since I'm not sure if it works in DB2 and I have not found live DB2 tester (it is required in PostgreSQL where I tested query).

Comparing all data in two tables whilst ignoring certain differences

I am currently trying to compare two SQL server database tables. I've found various methods online, some which seem to work, other which don't.
The one I used which worked was:
select * from table1
except
select * from table2
The only issue with this then (as far as I am aware) is, the table says there is a difference between a 'NULL' value and a '0'. Which is correct, there is a difference.
However my question is, is there a way to do the comparison difference check, whilst ignoring certain conditions such as NULL and 0.
You can use
select isnull(column1, 0) as column1 from table1
except
select isnull(column1, 0) as column1 from table2
to consider the values 0 and null as same.
Also, If you wish to consider more values as same like null = 0 = '' (empty string)
You can use case:
select case when (column1 is null or column1 = '') then 0 end as column1 from table1
except
select case when (column1 is null or column1 = '') then 0 end as column1 from table2

Is there a single SQL (or its variations) function to check not equals for multiple columns at once?

Just as I can check if a column does not equal one of the strings given in a set.
SELECT * FROM table1 WHERE column1 NOT IN ('string1','string2','string3');
Is there a single function that I can make sure that multiple columns does not equal a single string? Maybe like this.
SELECT * FROM table1 WHERE EACH(column1,column2,column3) <> 'string1';
Such that it gives the same effect as:
SELECT * FROM table1 WHERE column1 <> 'string1'
AND column2 <> 'string1'
AND column3 <> 'string1';
If not, what's the most concise way to do so?
I believe you can just reverse the columns and constants in your first example:
SELECT * FROM table1 WHERE 'string1' NOT IN (column1, column2, column3);
This assumes you are using SQL Server.
UPDATE:
A few people have pointed out potential null comparison problems (even though your desired query would have the same potential problem). This could be worked around by using COALESCE in the following way:
SELECT * FROM table1 WHERE 'string1' NOT IN (
COALESCE(column1,'NA'),
COALESCE(column2,'NA'),
COALESCE(column3,'NA')
);
You should replace 'NA' with a value that will not match whatever 'string1' is. If you do not allow nulls for columns 1,2 and 3 this is not even an issue.
No, there is no standard SQL way to do this. Barring any special constraints on what the string fields contain there's no more concise way to do it than you've already hit upon (col1 <> 'String1' AND col2 <> 'String2').
Additionally, this kind of requirement is often an indication that you have a flaw in your database design and that you're storing the same information in several different columns. If that is true in your case then consider refactoring if possible into a separate table where each column becomes its own row.
The most concise way to do this is
SELECT * FROM table1 WHERE column1 <> 'string1'
AND column2 <> 'string1'
AND column3 <> 'string1';
Yes, I cut & pasted that from your original question. :-)
I'm more concerned why you're wanting to compare against all three columns. It sounds like you might have a table that needs normalization. What are the actual columns of column1, column2 and column3. Are they something like phone1, phone2, and phone3? Perhaps those three columns should actually be in a subtable.