i have the following two tables:
Table1
id name
---------
A3 B2
A3 B400
A5 B100
A7 B200
A8 B6
A8 B2
A8 B3
and
Try with UNION DISTINCT like:
SELECT DISTINCT t1.id as ID,
t2.company as Company,
'FOUND' AS status
FROM table1 t1
JOIN table2 t2
ON t1.id = t2.id
group by ID
union distinct
SELECT DISTINCT t2.id as ID,
t2.company as Company,
'FOUND' AS status
FROM table1 t1
JOIN table2 t2
ON t1.name = t2.name
group by ID
union distinct
SELECT t1.name as ID,
t1.name as Company,
'NOT FOUND' AS status
FROM table1 t1
WHERE t1.name NOT IN (SELECT t2.name
FROM table2 t2)
GROUP BY ID
I think you can use a query like the following:
SELECT DISTINCT IF(name2 IS NULL, name, ID) AS ID,
IF(name2 IS NULL, name, Company) AS Company,
IF(name2 IS NULL, 'NOT FOUND', 'FOUND') AS Status
FROM (
SELECT DISTINCT
CASE
WHEN t1.id = t2.id THEN t1.id
WHEN t1.name = t2.name THEN t2.id
ELSE t1.id
END AS ID,
CASE
WHEN t1.id = t2.id THEN t2.company
WHEN t1.name = t2.name THEN t2.company
ELSE t1.name
END AS Company,
t1.name,
(SELECT Table2.name
FROM Table2
WHERE Table2.name = t1.name LIMIT 1) AS name2
FROM Table1 AS t1
LEFT JOIN Table2 AS t2 ON (t1.id = t2.id) OR (t1.name = t2.name)) AS t
ORDER BY ID;
The query use a single LEFT JOIN
operation plus a correlated subquery.
Demo here
There's something unclear about your queries, because they shouldn't execute as you've shown them (due to select
containing non-aggregates not in group by
). But based on your explanation of what you're trying to do...
You could use outer joins and then use case logic and/or coalesce to determine which value to use in each case.
SELECT DISTINCT
coalesce(t2_id.id, t2_name.id, t1.name) as ID
, coalesce(t2_id.company, t2_name.company, t1.name) as Conpany
, case when t2_id.id is not null or t2_name.name is not null
then 'FOUND'
else 'NOT FOUND'
end status
FROM table1 t1
LEFT JOIN table2 t2_id
ON t1.id = t2_id.id
LEFT JOIN table2 t2_name
ON t1.name = t2_name.name
Note that I used DISTINCT
to make sure the exact same row doesn't appear multiple times; but this may return multiple rows for an ID (with different Company values) depending on the data. I couldn't quite tell what was intended because the uses of DISTINCT
and GROUP BY
in the three queries as posted in the question didn't seem to add up for me.
These requirements are confusing enough it might be worth a re-assessment of your data model. I think the UNION
solution is your best bet possibly modified to use UNION ALL
for efficiency.
I did put together a mutex based hack that likely has as many subtle problems as any of the other queries on this page.
select
coalesce(t2.id, t1.name) AS ID,
coalesce(t2.company, t1.name) AS Company,
if(isnull(t2.id), 'NOT FOUND', 'FOUND') as Status
from (select 0 as mutex union select 1) as m
left join table1 as t1 on 1 = 1
left join table2 as t2 on t1.name = t2.name or (t1.id = t2.id and mutex)
group by coalesce(t2.id, t1.name)
That said, please test these queries carefully and look over your data and results. There's a whole lot of room for error depending on your input data.