Combining different Columns from different tables into distinct table - sql

I need to combine 3 different columns from 3 tables and result set should be a distinct table.
Attached to the blue table is my question and the yellow table is my expected answer. How Can I Get the expected table?
I don't want duplicates in the name which is column 1.
Any help will be appreciated.

Full Outer Joins
The question doesn't give us much to go on so I am making almost no assumptions about the data. There doesn't seem to be a 'Name' table and none of the 3 tables appears to represent a complete list of names. So, I'm going to close my eyes and type out a couple of full outer joins:
Select t1.name, t1.country, t2.food, t3.movie
from table1 t1
full outer join table2 t2 on t1.name = t2.name
full outer join table3 t3 on t3.name = t1.name
This will give you all of the names (with no assumptions that any one table would need to contain a complete list), each one listed just once (provided they don't already appear multiple times in any one table) along with any data associated with that name from any of the three tables.
Update
So here is an update (see comment below) that replaces the names of the countries, foods, and movies with just 'yes' or 'no'.
Select
t1.name,
case when t1.country is null then 'no' else 'yes' end as country,
case when t2.food is null then 'no' else 'yes' end as food,
case when t3.movie is null then 'no' else 'yes' end as movie
from table1 t1
full outer join table2 t2 on t1.name = t2.name
full outer join table3 t3 on t3.name = t1.name
...and rewritten with generic Column1, Column2 in case that's the issue:
Select
t1.Column1 as name,
case when t1.Column2 is null then 'no' else 'yes' end as country,
case when t2.Column2 is null then 'no' else 'yes' end as food,
case when t3.Column2 is null then 'no' else 'yes' end as movie
from table1 t1
full outer join table2 t2 on t1.Column1 = t2.Column1
full outer join table3 t3 on t3.Column1 = t1.Column1
I hope this helps.

So I came up with an answer to my question.
I used union function to get expected result.
Basically I had 3 tables with one same column name (number).
for instance 700 could be in table 1 and 3 but not in 2 and 701 could be only in table 1.
I used this query:
select Number, SUM(I) as Country, SUM(D) as Place, SUM(A) as City from
(
SELECT distinct(number), CASE WHEN m.number IS NULL THEN 0 ELSE 1 END AS I,0 AS D, 0 AS A
FROM dbo.country M(NOLOCK)
Union
SELECT distinct(number),0 as I,CASE WHEN D IS NULL THEN 0 ELSE 1 END AS D, 0 AS A
FROM dbo.Food F(NOLOCK)

Related

count duplicates in sql for 1 column

how i can fill out "category" in table 1 in the case where there are multiple in table 2? I would like to fill as multiple if there are multiple categories per object.
attempt:
select t1.*,
case case when count(t2.category)>1 then 'Multiple' else cast(t2,category as varchar)
from table1 t1
left join table 2 t2 on t2.object=t1.object
Issue, its asking for group by, i have over 80 columns, is there anyway to bypass group by?
Create an expression for the value using a subquery:
select
t1.*,
case (select count(*) from table2 t2 where t2.object = t1.object)
when 0 then 'None'
when 1 then (select cast(max(t2,category) as varchar)) from table2 t2 where t2.object = t1.object)
else 'Multiple'
end as category
from table1 t1
This avoids listing all columns in either the group by clause in the case of aggregation approach, or the select clause in the case of using a query over a subquery.
I added None as a result because you used a left join, indicating that joining rows are optional.
This wouldn't perform well with large numbers of rows, but should be fine with modest table sizes.
Can you try this:
select
distinct
t1.*,
case when c.object is not null then 'Multiple' else b.category end as category
from
table1 t1
left outer join
table2 t2
on t1.object = t2.object
left outer join
(select object from table2 group by object having count(*) > 1) c
on t1.object = c.object

sql server compare two column from different table

I have two table containing one columns in both table
table1
item
table2
item
I want a boolean result true/false if all the values in item column of table1 and table2 are exact match.
e.g columns values for both table
item item
apple apple
boy boy
cat cat
this should return true
item item
apple apple
boy boy
cat dog
should return false
You could check if records exist on one side or the other only by joining the two tables left-to-right and right-to-left. If there are any records not matched, it's false, otherwise true.
select case when exists (
select top 1 1
from Table1 t1
left join Table2 t2 on t2.item = t1.item
where t2.item is null
union all
select top 1 1
from Table2 t2
left join Table1 t1 on t1.item = t2.item
where t1.item is null
)
THEN 'false'
ELSE 'true'
END as result
You can use full join and aggregation:
select (case when count(*) = 0 then 'true' else 'false' end)
from t1 full join
t2
on t1.item = t2.item
where t1.item is null or t2.item is null;
This counts misses. If there are none, then the tables are the same.
Or without the where clause:
select (case when count(t1.item) = count(t2.item) then 'true' else 'false' end)
from t1 full join
t2
on t1.item = t2.item
where t1.item is null or t2.item is null;
Note: Like the data in your question, and the question in general, this assumes that the items are unique.

SQL CASE WHEN in table

I have two tables: table1 and table2 both with one column for ID. I want to create a column in table1 that displays 'Y' if ID in table1 is in table2 and 'N' if it is not.
Currently, I am using:
Select id, case when id in (table2) then 'Y' else 'N' end as in_table2
from table1
However, since both tables are very big, the query is taking forever. Is there a more efficient way of doing this?
Thanks
Use exists:
Select t1.id,
(case when exists (select 1 from table2 t2 where t2.id = t1.id)
then 'Y' else 'N'
end) as in_table2
from table1 t1;
This should be much quicker and efficient than using exists/subqueries:
SELECT t1.id ,
CASE WHEN t2.id IS NULL
THEN 'N'
ELSE 'Y'
END AS in_table2
FROM table1 t1
LEFT JOIN TABLE2 t2 ON t1.id = t2.id;
By left joining you maintain visibility of the records on table2, and if the ID is null, you know it exists on table1 but not on table2, so you can safely use a case statement to show Y or N based on t2.id.

Compare 2 Tables and return full data

Im struggling with writing a query and infact do not know which query is relevant for the task (Union, Inner/Outer Join etc)
I have a table of data that is revised each week and I need to report on the differences.
i.e if it gets deleted in table 1, table 2 or a field changes.
I have included an image to show the data from the revised table and also what I would like as an output to report on (Ignore the Comments, they are only for reference)
Any help would be appreciated.
I don't believe access supports full outer joins ...
so... we use a left join and a right join and a union along with a case statement.
Select A.*, case when T1.Name=T2.Name and T1.Area=T2.Area then 'In T1 and T2 and Equal'
when T2.Name is null then 'In T1 Only'
when T1.Name is null then 'in T2 Only,omitted in T1'
when T1.Name = T2.Name and T1.Area<> T2.Area then 'In T1 and T2 Different area' from (
Select t1.*, T2.*
FROM table1 T1
LEFT JOIn table2 T2
on T1.Name = T2.Name and T1.Area = T2.Area
UNION
Select t1.*, T2.*
FROM table1 T1
RIGHT JOIN table2 T2
on T1.Name = T2.Name and T1.Area = T2.Area) A
FULL OUTER JOIN to find any rows from table 1 or table 2 and align them whenever possible then you can use a CASE to create the comment column based on the comparison of AREA, or NAME being null.
But MS ACCESS doesn't have FULL JOIN so we need LEFT JOIN UNION RIGHT JOIN.
Also CASE statement is VB syntax, use switch
SELECT
t1.*,
t2.*,
switch(
t2.name IS NULL,'IN TABLE 1 ONLY',
t1.area <> t2.area,'IN TABLE 1 AND 2 SAME NAME BUT AREA DIFFERENT IN TABLE 2',
true,'IN TABLE 1 AND 2 AND EQUAL')
FROM table1 AS t1
LEFT JOIN table2 AS t2
ON t1.name = t2.name
UNION
SELECT
t1.*,
t2.*,
switch(
t1.name IS NULL,'IN TABLE 2 ONLY, OMITTED IN TABLE 1',
t1.area <> t2.area,'IN TABLE 1 AND 2 SAME NAME BUT AREA DIFFERENT IN TABLE 2',
true,'IN TABLE 1 AND 2 AND EQUAL')
FROM table1 AS t1
RIGHT JOIN table2 AS t2
ON t1.name = t2.name

Table join comparing and creating a new column using that compare

I have 2 tables... table1 and table2.
I want to display all serial numbers from table1
table2 has also has serial numbers in it
I would like to compare the serial numbers in table1 with table2
I would then like to display all the serial numbers in table1 and have a second column with a yes if the serial number was in table1 or a no if it wasn't
Is this possible to do with a sql statement or do I have to build a seperate table? i'm running sql-server.
If serial numbers in each table are unique then you could use:
SELECT Table1.SerialNumber,
CASE WHEN Table2.SerialNumber IS NULL THEN 'No' ELSE 'Yes' END AS [IsInTable2]
FROM Table1.SerialNumber
LEFT JOIN Table2
ON Table2.SerialNumber = Table1.SerialNumber
If there are Duplicates in one or both tables then either of the following will work:
SELECT DISTINCT
Table1.SerialNumber,
COALESCE([IsInTable2], 'No') [IsInTable2]
FROM Table1.SerialNumber
OUTER APPLY
( SELECT TOP 1 'Yes' [IsInTable2]
FROM Table2
WHERE Table2.SerialNumber = Table1.SerialNumber
) Table2
SELECT DISTINCT
Table1.SerialNumber,
CASE WHEN Table2.SerialNumber IS NULL THEN 'No' ELSE 'Yes' END [IsInTable2]
FROM Table1.SerialNumber
LEFT JOIN
( SELECT DISTINCT SerialNumber
FROM Table2
) Table2
ON Table2.SerialNumber = Table1.SerialNumber
If we assume that the serial numbers are unique in each table then you can do an outer join. Using a LEFT OUTER JOIN will grab you all rows from the left side and optionally grab you any matching rows on the right side. Then you can do a comparison to see if a matching row was found in table2.
SELECT t1.serial, CASE WHEN t2.serial IS NULL THEN 'No' ELSE 'Yes' END
FROM table1 t1
LEFT OUTER JOIN table2 t2 ON t1.serial = t2.serial;
Try this
SELECT t1.serialnumber as serialnumber, Case
WHEN t1.serialnumber = t2.serialnumber then 'YES' else 'NO' END
FROM table1 t1
LEFT JOIN table2 t2 with (nolock) on t1.serialnumber = t2.serialnumber;
Hopefully that should work