Insert values from multiple column in single column - sql

I am comparing data from two tables - Table A and Table B. I would like to create temporary table or view which will only return the mismatched records and store the mismatched messages from every column into single column .
I only have read permission to Database so is there a way to get the desired output creating Views/?
Data looks like this:
FirstNameCheck
EmailCheck
TelephoneCheck
TableAFirstName
TableAEmail
TableATelephone
TableBFirstName
TableBEmail
TableBTelephone
MATCHED
MATCHED
MISMATCHED IN TELEPHONE
Pano
abc#gmail.com
123222
Pano
abc#gmail.com
NULL
MATCHED
MISMATCHED IN EMAIL
MISMATCHED IN TELEPHONE
Brian
esd#gmail.com
NULL
Brian
NULL
123456
MATCHED
MATCHED
MATCHED
William
NULL
132777
William
NULL
132777
MATCHED
MATCHED
MISMATCHED IN TELEPHONE
Bill
NULL
145678
Bill
NULL
145669
MATCHED
MATCHED
MISMATCHED IN TELEPHONE
Robin
NULL
132444
Robin
NULL
132456
Expected result:
Error_Message
TableAFirstName
TableAEmail
TableATelephone
TableBFirstName
TableBEmail
TableBTelephone
MISMATCHED IN TELEPHONE
Pano
abc#gmail.com
123222
Pano
abc#gmail.com
NULL
MISMATCHED IN EMAIL--MISMATCHED IN TELEPHONE
Brian
esd#gmail.com
NULL
Brian
NULL
123456
MISMATCHED IN TELEPHONE
Bill
NULL
145678
Bill
NULL
145669
MISMATCHED IN TELEPHONE
Robin
NULL
132444
Robin
NULL
132456
Query which I tried and got stuck to get new column with error_messages
SELECT column1, 2
FROM (query-which gives the sample data)
WHERE (FirstNameCheck = 'MISMATCHED IN FIRST NAME' OR EmailCheck = 'MISMATCHED IN EMAIL' OR TelephoneCheck = 'MISMATCHED IN TELEPHONE')
Can someone please help me how to do this?
Thanks in advance

I used CASE expressions and CONCAT_WS to accomplish this. Long story short, I nullify "match" instances and then concatenate the mismatches into one column.
Note: CONCAT_WS only works on SQL Server 2017 or later. If you're on an earlier version of SQL Server just use the regular CONCAT function.
SQL:
SELECT
CONCAT_WS(' -- ', [FirstNameCheck_MisMatch], [EmailCheck_MisMatch], [TelephoneCheck_MisMatch]) AS Error_Message,
a.[TableAFirstName],
a.[TableAEmail],
a.[TableATelephone],
a.[TableBFirstName],
a.[TableBEmail],
a.[TableBTelephone]
FROM
(SELECT
CASE WHEN a.[FirstNameCheck] <> 'MATCHED' THEN a.[FirstNameCheck] END AS [FirstNameCheck_MisMatch],
CASE WHEN a.[EmailCheck] <> 'MATCHED' THEN a.[EmailCheck] END AS [EmailCheck_MisMatch],
CASE WHEN a.[TelephoneCheck] <> 'MATCHED' THEN a.[TelephoneCheck] END AS [TelephoneCheck_MisMatch],
a.[FirstNameCheck],
a.[EmailCheck],
a.[TelephoneCheck],
a.[TableAFirstName],
a.[TableAEmail],
a.[TableATelephone],
a.[TableBFirstName],
a.[TableBEmail],
a.[TableBTelephone]
FROM
ERROR_CHECK a) a
/* RETURN ONLY RECORDS WHERE MISMATCH HAPPEN */
WHERE
COALESCE(a.[FirstNameCheck_MisMatch], a.[EmailCheck_MisMatch], a.[TelephoneCheck_MisMatch]) IS NOT NULL;
Result:
Error_Message
TableAFirstName
TableAEmail
TableATelephone
TableBFirstName
TableBEmail
TableBTelephone
MISMATCHED IN TELEPHONE
Pano
abc#gmail.com
123222
Pano
abc#gmail.com
(null)
MISMATCHED IN EMAIL -- MISMATCHED IN TELEPHONE
Brian
esd#gmail.com
(null)
Brian
(null)
123456
MISMATCHED IN TELEPHONE
Bill
(null)
145678
Bill
(null)
145669
MISMATCHED IN TELEPHONE
Robin
(null)
132444
Robin
(null)
132456
SQL Fiddle:
http://sqlfiddle.com/#!18/2a640e/11

Related

Conditionally mapping column names to row values

Assume that we have a table where we have one field for zip code and the rest are binary fields (1 or NULL) with names corresponding to various places. For example, imagining the table has 201 fields with the first field titled "zip code" containing zip codes and the latter being 200 binary value fields titled with city names: Chicago, New York, Houston, etc.
Assume that row one contains zip code 11373. While one could use coalesce to find the first non-null value and return "New York" another value like "Elmhurst" may also be true.
zip_code new_york chicago elmhurst dover maspeth
10001 1 NULL NULL NULL NULL
07801 NULL NULL NULL 1 NULL
11373 1 NULL 1 NULL 1
The goal is to map the column names to each respective zip code and get an output like so:
zip_code city
10001 new_york
07801 dover
11373 new_york
11373 elmhurst
11373 maspeth
Any help is much appreciated.
This is a great use case for SQL UNPIVOT:
SELECT unpvt.*
FROM
#x UNPIVOT (v FOR statename IN (new_york, chicago,elmhurst, dover, maspeth)) AS unpvt
One method uses union all:
select zip_code, 'New York' as city from t where new_york = 1
union all
select zip_code, 'Chicago' as city from t where chicago = 1
union all
. . .

Name Correction

Name Correction
As the wedding season is on, John has been given the work of printing guest names on wedding cards. John has written code to print only those names that start with upper-case alphabets and reject those that start with lower-case alphabets or special characters.
Your job is to do the following:
1.Correct the rejected names (names which start with lower case or with a special character). You have to change the first alphabet of the rejected name to Upper case and in the case of special character there will be no change.
2.Output the newly corrected names in ascending order.
Table format
Table: person
Field Type
name varchar(20)
Sample
Sample person table
name
mohit
Kunal
manoj
Raj
tanya
#man
Sample output table
name
#man
Manoj
Mohit
Tanya
Solution Attempted: IN SQL SERVER 2014
select name
from person as per
where (left(per.name,1) like '%[^A-Z]%' or left(per.name,1) like '% %')
union
select Upper(left(per.name,1))+right(per.name,len(per.name)-1)
from person as per
where left(per.name,1)<>left(Upper(per.name),1)
collate Latin1_General_CS_AI
order by per.name
Sample Test Cases Passes,
Still getting wrong answer in some competitor exam.
Please suggest what test case i have not handled.
Since you are only interested in correcting lower case and reporting special characters in the first character position I would use ascii comparision rather than regex.
select name, ascii(left(name,1)),
case
when ascii(left(name,1)) between 97 and 122 then
concat(char(ascii(left(name,1)) - 32),substring(name,2,len(name) -1))
else name
end name
from t
where ascii(left(name,1)) <= 64 or
ascii(left(name,1)) >= 91

AND/OR where clause logic confusion

So I have this table for customers with Main and Mobile phones. I either have a valid number or a blank space or a value of NULL.
CustName MainPhone MobilePhone
Joe 800-111-1234 321-123-1234
Jack 321-321-1237
Jill
Jimmy 321-123-1234
James NULL 432-322-2222
So I have 5 records in total and I want to filter out CustNames that have a blank on both Main and Mobile. So I checked first to see how many I had and used this WHERE CLAUSE:
Select *
From MyTable
Where (MainPhone = '' and MobilePhone = '')
and yes this returned one record only, in this case Jill which has no numbers in either fields.
Now if I want to list everyone except the records that have a blankspace on both MainPhone and MobilePhone what would the WHERE CLAUSE look like? I've tried a few variations and I'm not getting the proper results.
The Final resultset should be like this
CustName MainPhone MobilePhone
Joe 800-111-1234 321-123-1234
Jack 321-321-1237
Jimmy 321-123-1234
James NULL 432-322-2222
Thanks
Check this query
Select *
From mytable
Where (MainPhone != '' AND MainPhone IS NOT NULL) OR (MobilePhone != '' AND MobilePhone IS NOT NULL)
fiddle for the same
http://sqlfiddle.com/#!6/5e668/2
Select *
From MyTable
Where (ISNULL(MainPhone, '') = '' and ISNULL(MobilePhone, '') = '')

ANSI equivalent of IS NULL

I am trying to find the ANSI way to write the T-SQL 'IS NULL'. (corrected, was 'IN NULL')
Some posts on the internet say you can use coalesce to make it work like 'IS NULL'
The reason I like to do this: portable code. And the query must return the rows that are NULL.
So far I created this:
SELECT empid,
firstname,
lastname,
country,
coalesce(region,'unknown') AS regions ,
city
FROM HR.Employees
The result set looks like:
empid firstname lastname country regions city
1 Sara Davis USA WA Seattle
2 Don Funk USA WA Tacoma
3 Judy Lew USA WA Kirkland
4 Yael Peled USA WA Redmond
5 Sven Buck UK unknown London
6 Paul Suurs UK unknown London
7 Russell King UK unknown London
8 Maria Cameron USA WA Seattle
9 Zoya Dolgopyatova UK unknown London
I identified the rows that are NULL, but how do I filter them out of this set?
Both IS NULL and COALESCE are ANSI standard and available in almost all reasonable databases. The construct that you want, I think, is:
where region IS NULL
This is standard syntax.
To have COALESCE work like IS NULL requires a value that you know is not in the data:
where coalesce(region, '<null>') <> '<null>'
However, you would need different values for dates and numbers.
You seem to be confusing IS NULL (a predicate that checks to see if a value is null) and the T-SQL specific function ISNULL(value, replace) (no space and parameters after it), which is similar, but not identical to COALESCE.
Please see SQL - Difference between COALESCE and ISNULL? for details on how COALESCE and ISNULL differ for T-SQL.
Minor differences like what type is returned and what happens when all the arguments are null aside, ISNULL is a function that returns the first argument if it is not null, or the second argument if it is. COALESCE returns the first non-null argument (it can take more than two).
As a result, each of these might be used to solve your problem in different ways and with slightly different results.
IS NULL is valid ANSI SQL-92, is called the null predicate.
<null predicate> ::= <row value constructor> IS [ NOT ] NULL
See SQL-92, paragraph 8.6.
So WHEREcolumn nameIS NULL is perfectly valid.
The bit where ANSI SQL treats NULL values different from T-SQL is when you write WHERE column name = NULL or WHERE column name <> NULL. See SET ANSI NULLS (Transact-SQL).

Oracle null values

Can somebody please explain the functionality of the below query in oracle db and why is it not returning the last null row. And also please explain me not in functionality in case of null values.
Table Store_Information
store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
San Francisco $300 Jan-08-1999
Boston $700 Jan-08-1999
(null) $600 Jan-10-1999
SELECT *
FROM scott.Store_Information
WHERE store_name IN (null)
STORE_NAME SALES DATE
-------------------- -------------------- -------------------------
0 rows selected
SELECT *
FROM scott.Store_Information
WHERE store_name IS null;
NULL can not be "compared" as other (real) values. Therefor you have to use IS NULL or IS NOT NULL.
Here is a series of blog posts regarding this topic: http://momjian.us/main/blogs/pgblog/2012.html#December_26_2012
If the value you are looking for is a null value, the query should be:
SELECT *
FROM scott.Store_Information
WHERE store_name IS NULL;
Oracle NULLS are special:
nothing is equal to null
nothing is NOT equal to null
Since in is equivalent to a = any, this applies to in also.
So, you cannot use NULL in an in or not in clause and expect proper results.
Null is a special value which doesn't follow normal conventions of string or numeric comparison. Evaluating null using these common methods will always evaluate to FALSE unless you use some of the special built in functions.
Select * from Store_Information
where nvl(store_name,'') in ('')
Select * from store_information
where coalesce(store_name, 'Missing') in ('Missing')
Select * from store_information
where store_name is null
If you want your query select field with null value you can :
solution 1 :
use where ... IS NULL ...
solution 2 :
or if you want absolutely use a IN you can use a NVL
eg :
SELECT *
FROM scott.Store_Information
WHERE NVL(store_name, 'NULL_STORE_NAME') IN ('NULL_STORE_NAME')
but in the second case you make the assumption that you can't have a store name named 'NULL_STORE_NAME'... so usually it's better to use solution 1 in my opinion...