SQL query to find empty values with complex condition - sql

I have primary table (table1 - contains customer main information) that is related to another table (table2 - contains customer contact information) and common value is ID.
In primary table the ID value gives me 1 row, another table may gives me more rows, depending on how many contact types the customer has, for example:
main_phone (this row always exists)
home_phone
work_phone
mobile etc.
What I am trying to achieve:
First I want to check mobile value, if row is missing or there is no mobile value, but row exists then I want to check main_phone value.
But if there is mobile value then I don't want to check the main_phone value.
If main_phone value also missing then I want these records.
Currently I have query:
Select customer
From table1 t1
Join table2 t2 on t1.id = t2.id
Where t2.type in (main_phone, mobile)
And t2.type_values in ('',null,'-')
but the problem is, if customers has mobile number and missing phone number, these client records also show up in the result.

this might get you close..
SELECT customer
FROM table1 t1
WHERE NOT EXISTS (
SELECT 1
FROM table2 t2
WHERE t1.id = t2.id
AND t2.type in (main_phone, mobile)
and ISNULL(t2.type_value,'') NOT IN ('','-')
)
if it finds a value in the NOT EXISTS query it will be excluded

You have to be careful and treat null as a special value. The two queries below will return different results.
Select COUNT(*) from table1 t1
join table2 t2 on t1.id=t2.id
where t2.type in (main_phone, mobile)
and t2.type_values in ('',null,'-')
Select COUNT(*) from table1 t1
join table2 t2 on t1.id=t2.id
where t2.type in (main_phone, mobile)
and (t2.type_values IS NULL) OR(t2.type_values in ('','-'))
You should get in the habit of testing for null using a null comparison such as X IS NULL, NOT X IS NULL, ISNULL() or COALESCE().

did you want something like this?
SELECT
customer
FROM
table1 t1 JOIN
(SELECT
id
FROM
table1 t1 JOIN
table2 t2 ON
t1.id=t2.id
WHERE
t2.TYPE = mobile AND
(t2.type_values IS NULL OR
t2.type_values IN ('','-') )) missing_mobile ON
t1.id = missing_mobile.id
WHERE
t2.TYPE = main_phone AND
(t2.type_values IS NULL OR
t2.type_values IN ('','-') )

Related

How do I only import unique records into a table from another table?

I am trying to update a table in SQL Server. Table is called table1 with columns(code, desc). I want to update table1 with unique records from table2(code, desc). table2 is a copy of table1 but it contains records that are not present in table1.
EDIT 1: table1 consists of all the records in our ERP when exported in July, table2 consists of all the records in our ERP when exported in November (including records added after July which are the records that I want to add to table1)
To update table1.desc with values from matching rows in table2 simply do:
update t1 set
t1.desc = t2.desc
from table1 t1
join table2 t2 on t2.code = t1.code;
If however you want to insert rows into table1 that only exist in table2 (it's not exactly clear if that's the case) you can use not exists
insert into table1 (code, desc)
select code, desc
from table2 t2
where not exists (select * from table1 t1 where t1.code = t2.code);
Sounds like you want an INSERT
Something like this should work:
INSERT INTO table1 (code, desc)
SELECT t2.code, t2.desc
FROM table2 t2
LEFT JOIN table1 t1 on t2.code = t1.code and t1.desc = t2.desc
WHERE t1.code is null --Ignore records that already exist in table1
... Adjust join clause accordingly.

Join tables based on condition in Hive

I have two tables and have mentioned the layout of tables in the below screenshot.
Using Id column I need to join two tables. Whenever there is a match with Id (example Id is a2), I need to take the corresponding values from Table2. In some scenario, Id from Table1 will not be there in Table2 (example Id is a1). In that case, I have to take values from Table2 where the value of Id in Table2 is all.
For better clarification, I have mentioned the Expected output in the below screenshot.
I tried the below code, but don't seem to be working.
select distinct t1.Id,t1.Name,t2.Phone1,t2.Phone2
from Table1 t1
left join Table1 t2 on t1.Id = case when t2.Id is null then t1.Id else t2.Id end
Any help is greatly appreciated.
You can use two left joins, where the second brings in the default values:
select t1.*, coalesce(t2.phone1, t2d.phone1) as phone1, coalesce(t2.phone2, t2d.phone2) as phone2
from table1 t1 left join
table2 t2
on t1.id = t2.id left join
table2 t2d
on t2d.id = 'All' and t2.id is null;

Select all from one table where some columns match another select

I have two differents tables. The have some columns in common, for this example lets say 'name' and 'id'.
By making
( SELECT name,id FROM table1
EXCEPT
SELECT name,id FROM table2)
UNION ALL
( SELECT name,id FROM table2
EXCEPT
SELECT name,id FROM table1)
I get a list of the elements that are on one tablet but not in the other one.
Up to this point everything is OK.
But now, I want to make a select all from table1 where the name and the id matches the result of the query above.
After lots of comments I think this is what you're after...
SELECT T1.*
FROM table1 t1
LEFT JOIN table2 t2
on T1.ID = T2.ID
and T1.Name = T2.Name
AND E2.event_Time_UTC between convert(datetime,'2016-02-09 00:00:20',101) and convert(datetime '2016-02-09 23:59:52',101)
WHERE T2.Name is null
AND E1.Event_Time_UTC between convert(datetime,'2016-02-09 00:00:20',101) and convert(datetime,'2016-02-09 23:59:52',101)
You may allow implicit casting to work but above is the explicit approach.
If not then you would need to cast the string dates to a date time, assuming Event_Time_UTC is a date/time datatype.
A left join lets us return all records from the 1st table and only those that match from the 2nd.
The t1.* returns only the columns from table1. The join criteria (on) allows us to identify those records which match so they can then be eliminated in the where clause by 'where t2.name is null' they will always be null when no record match in t2.
Thus you get a result set that is: all records from t1 without a matching record on name and id in table2.
Old version
The below content is no longer relevant, based on comments.
I redacted previous answer a lot because you're using SQL Server not MySQL and I know you want multiple records not table1 and table2 joined.
In the below I create two tables: table1 and table2. I then populate table1 and table2 with some sample data
I then show how to get only those records which exist in one table but not the other; returning a separate ROW for each. I then go into detail as to why I choose this approach vs others. I'll finally review what you've tried and try to explain why I don't think it will work.
create table table1 (
ID int,
name varchar(20),
col1 varchar(20),
col2 varchar(20),
col3 varchar(20));
Create table table2 (
id int,
name varchar(20));
Insert into table1 values (1,'John','col1','col2','col3');
Insert into table1 values (2,'Paul','col1','col2','col3');
Insert into table1 values (3,'George','col1','col2','col3');
Insert into table2 values (1,'John');
Insert into table2 values (4,'Ringo');
Option 1
SELECT T1.name, T1.ID, T1.Col1, T1.Col2, T1.Col3
FROM Table1 T1
LEFT JOIN Table2 T2
on T1.Name = T2.Name
and T1.ID = T2.ID
WHERE T2.ID is null
UNION ALL
SELECT T2.name, T2.ID, NULL, NULL, NULL
FROM Table1 T1
RIGHT JOIN Table2 T2
on T1.Name = T2.Name
and T1.ID = T2.ID
WHERE T1.ID is null ;
which results in...
Notice John isn't there as it's in both tables. We have the other 2 records from table1, and the ID, name from table2 you're after.
Normally I would do this as a full outer join but since I think you want to reuse the name and id fields to relate to BOTH tables in the same column we had to use this approach and spell out all the column names in table 1 and put NULL for each column in table1 when displaying records from table2 in order to make the output of the second query union to the first. We simply can't use *
Option 2: Using a full outer join... with all columns from T1
SELECT T1.*
FROM Table1 T1
FULL OUTER JOIN Table2 T2
on T1.ID = T2.ID
and T1.Name = T2.Name
WHERE (T1.ID is null or T2.ID is null)
you get this... which doesn't show Ringo...
But then I would ask why you need anything from Table 2 at all so I think you're wanting to still show the ID, Name from table2 when it doesn't exist in table1.
Which is why What I think you're after is the results from the 1st query using the union all.
Option 3 I suppose we could avoid the second query in option 1 by doing...
SELECT coalesce(T1.Name, T2.name) as name, coalesce(T1.Id,T2.ID) as ID, T1.col1, T1.Col2, T1.Col3
FROM Table1 T1
FULL OUTER JOIN Table2 T2
on T1.ID = T2.ID
and T1.Name = T2.Name
WHERE (T1.ID is null or T2.ID is null)
which gives us what I believe to be the desired results as well.
This works because we know we only want the name,id from table2 and all the column values in table1 will be blank.
Notice however in all cases we simply can't use Tablename.* to select all records from table1.
This is what you tried:
( SELECT name,id FROM table1
EXCEPT
SELECT name,id FROM table2)
UNION ALL
( SELECT name,id FROM table2
EXCEPT
SELECT name,id FROM table1)
Assuming you want to reuse the ID, Name fields; you can't select *. Why? because the records in Table2 not in table1 aren't in table1. In my example if you want Ringo to show up you have to reference table2! Additionally, * gives you no ability to "Coalesce" the ID and name fields together as I did in option 3 above.
If you ONLY want the columns from table1, that means you will NEVER see data from table2. If you don't need the data from table2, (such as ringo in my example) then why do we need to do the union at all?) I'm assuming you want ringo, thus you HAVE to somewhere reference name, id from table2.
You could also do this with NOT EXISTS:
SELECT *
FROM table1
WHERE
NOT EXISTS
(SELECT 1
FROM table2
WHERE table1.id = table2.id
AND table1.name = table2.name)
;with cte as
(
( SELECT name,id FROM table1
EXCEPT
SELECT name,id FROM table2)
UNION ALL
( SELECT name,id FROM table2
EXCEPT
SELECT name,id FROM table1)
)
Select *
from table1 as tbl1
where
tbl1.id = cte.id
and tbl1.name = cte.name

SQL Insert Data If Column A Matches and Column B Doesn't

I have a SQL Insert statement that needs to insert records into another table only if the the record doesn't exist in table2 or the zip code has changes in table1. I have tried the following but it throws an error and it is the logic I am looking for:
INSERT INTO table2
SELECT id, zip
FROM table1 t1
JOIN table2 t2
ON t1.id = t2.id and t1.zip <> t2.zip
I also need it to insert the records if the id doesn't exist at all in table2. I have googled the crap out of this and can't seem to find the solution anywhere.
What about this?
INSERT INTO table2
SELECT t2.id, t2.zip
FROM table1 t1
LEFT OUTER JOIN table2 t2
ON t1.id = t2.id
WHERE (t1.id IS NULL OR t2.zip <> t1.zip)
Also, be sure to clarify which table's id and zip columns you are asking for.
You should always include column lists when doing inserts. Second, your query doesn't quite capture your logic. You need a left outer join to find the records that don't exist in the second table. Perhaps this might do what you want:
INSERT INTO table2(id, zip)
SELECT id, zip
FROM table1 t1 LEFT JOIN
table2 t2
ON t1.id = t2.id
WHERE (t1.zip <> t2.zip) or (t2.zip is null)
You just need a WHERE NOT EXISTS clause
INSERT INTO table2
SELECT id, zip
FROM table1
WHERE NOT EXISTS (SELECT 1 FROM table2 WHERE table2.id = table1.id AND table2.zip = table1.zip)

SQL Query: select all the records from table1 which exist in table2 + all the records from table2 which don't exist in table1

consider the following example.
I have to select all the records from table1 which exist in table2 also + all the records from table2 which don't exist in table1 but exist in table2 and have IsActive=1 and status not null.
I initially tried it with a join but how to do the later part where I have to select the records which don't exist in table 1 ? I have to do it inside a single query presumably with a SQL view.
Edit
I need to combine the results like a UNION of 2 tables, so incase of rows absent in table1 but present in table2, the columns of belonging to table1 would be blank.
Here's an example query:
select *
from Table2 t2
left join
Table1 t1
on t1.id = t2.id
where t1.id is not null
or (isActive = 1 and status is not null)
The first line of the where clause takes care of "all the records from table1 which exist in table2". The second line is for "don't exist in table1 but exist in table2 and have IsActive=1 and status not null".
You will need an outer join here.
http://msdn.microsoft.com/en-us/library/ms187518.aspx
Is this it? Not sure if I got right what you want to do.
SELECT
*
FROM
Table1 t1
JOIN
Table2 t2 ON (t1.ID = t2.ID OR (t1.ID IS NULL AND t2.isActive = 1 AND t2.Status IS NOT NULL))