MySQL: Get results from two tables, count matches in a third - mysql

I have three tables, all of which share a common field (our_id).
our_id is the primary key in Table1.
our_id also exists zero or more times in Table2 and Table3.
I want to select records where our_id exists in both Table1 and Table2, but I also need to count how many times our_id occurs in Table3 (or even just whether our_id exists or not in Table3).
I came up with this:
SELECT Table1.*, Table2.*, COUNT(Table3.*) AS table3_count
FROM Table1, Table2, Table3
WHERE Table1.our_id = Table2.our_id
AND Table1.our_id = Table3.our_id;
…but that only returns results where our_id exists in Table3, which it may not do.
So I tried:
SELECT Table1.*, Table2.*, COUNT(Table3.*) AS table3_count
FROM Table1, Table2, Table3
WHERE Table1.our_id = Table2.our_id
AND (Table1.our_id = Table3.our_id
OR NOT EXISTS (SELECT * FROM Table3
WHERE Table1.our_id=Table3.our_id));
But that just ran and ran…
I need it to still return results where our_id exists in both Table1 and Table2, and tell me how many times (or whether) it exists in Table3.
Thank you in advance!

You should use a LEFT JOIN to bring in Table3. A LEFT JOIN returns all rows from the left table (Table1) and attempts to match the rows in the right table (Table3). If Table3 does not have any rows that match, NULL is returned for the selected Table3 fields.
SELECT Table1.*, Table2.*, t3.count
FROM Table1, Table2
LEFT JOIN (SELECT our_id, COUNT(*) AS count FROM Table3 GROUP BY our_id) t3
ON Table1.our_id = t3.our_id
WHERE Table1.our_id = Table2.our_id

Related

Combining two Access Queries

I three tables. Table1, Table2, Table3. They all have a field called KB. Can I have one query to accomplish: Get all the information from table2, when Table1 KB = Table2 KB But only if table1 KB doesn't exist in Table3. I currently have 2 Queries. One to determine which KBs in Table1 don't exist in Table3. I then run a query against those results showing me all the records in Table2 that have matching KB. Can I do that all in 1 query, or 2 queries the best way?
You can do it with a combination of EXISTS and NOT EXISTS:
SELECT t2.*
FROM table2 AS t2
WHERE EXISTS (SELECT 1 FROM table1 AS t1 WHERE t1.KB = t2.KB)
AND NOT EXISTS (SELECT 1 FROM table3 AS t3 WHERE t3.KB = t2.KB)
or with an INNER join of table2 to table1 and a LEFT join of table2 to table1 from which you will return only the non matching rows:
SELECT t2.*
FROM (table2 AS t2 INNER JOIN Table1 ON t2.KB = Table1.KB)
LEFT JOIN table3 ON t2.KB = table3.KB
WHERE table3.KB IS NULL
This may return duplicate rows of table2 if the relationship of table2 and table1 is 1:n, so in this case you can use DISTINCT:
SELECT DISTINCT t2.*
....................

More rows after Left Join in MySQL

I've two tables, table1 contains 22780 rows. Now I left join table1 with table2 (which doesn't contain any duplicates) and I get 23588 rows.
SELECT * FROM Table1
left join Tabelle6 ON CAST(Table1.Customer AS Int) = table2.Customer
Why do I get more rows now? I only need every row from table1 once.
Edit: found my issue, table 2 does contain duplicates. But is there any way to join every row only once and ignore any further matches?
As the comment suggests, the easiest way to handle this would probably be to do SELECT DISTINCT to remove duplicates from your result set:
SELECT DISTINCT
t1.col1,
t1.col2,
t1.Customer,
...
FROM Table1 t1
LEFT JOIN Table2 t2
ON CAST(t1.Customer AS Int) = t2.Customer
But there is another option here. We could also join to a subquery which removes duplicate customers. This would ensure that no record from the first table gets duplicated from matching to more than one record in the second table.
SELECT *
FROM Table1 t1
LEFT JOIN
(
SELECT DISTINCT Customer
FROM Table2
) t2
ON CAST(t1.Customer AS Int) = t2.Customer

Joining multiple columns in table1 with multiple columns in table2 with additional condition MySql

I have table_1 with unique records of IDs and multiple columns of data
and
table_2 with multiple rows concerning particular ID and multiple columns. One of the column in table2 is, say, time_lapse.
I need those two tables joined with all columns saved but with only those rows from table2 with highest time_lapse value.
I was trying this way...
create table as new_table
select table1.*, table2.* from
table1 left join table2
on table1.id=table2.id
where time_lapse=
(select max(time_lapse) from table2
group by id);
... but it failed.
Any suggestions for a newbie? Thank you.
You are close. But you are selecting the maximum time_lapse per id and then you act as if you had only selected one record with only one time_lapse. Use IN and have the id in the select list of your subquery:
create table as new_table
select table1.*, table2.* from
table1 left join table2
on table1.id=table2.id
where (table2.id, table2.time_lapse) in
(select id, max(time_lapse) from table2
group by id);
Then you are outer-joining table2, but want certain criteria on it in the WHERE clause. That doesn't work (as columns in outer-joined records are null).
The same query a tad prettier with a real outer join:
create table as new_table
select t1.*, t2.*
from table1 t1
left join table2 t2 on t1.id = t2.id
and (t2.id, t2.time_lapse) in
(select id, max(time_lapse) from table2 group by id);

SQL - show results from table without values from another table

I need to show only results which are in Table1 and Table2 but are not in Table3. Basically, it should be something like TABLE1, Table2 except INNER JOIN between (TABLE1, Table2) and TABLE3.
Should looks like this - On left side Table1 and Table2, on right side Table3
Now I have this:
SELECT mesta_email, mesta_kod
FROM Table1
UNION ALL
SELECT mesta_email, mesta_kod
FROM Table2
// And somehow except values which are in Table3
Can somebody help me please? Thanks a lot.
There are a couple different ways to do this. I believe mysql does better with the outer join/null approach:
select t.*
from (
SELECT mesta_email, mesta_kod
FROM Table1
UNION ALL
SELECT mesta_email, mesta_kod
FROM Table2
) t left join Table3 t3 on t.mesta_email = t3.mesta_email
and t.mesta_kod = t3.mesta_kod
where t3.mesta_email is null
This assume table3 shares the same structure as the other 2 tables.
I would approach the problem almost directly as you write it, using exists and not exists:
select t1.mesta_email, t2.mesta_kod
from table1 t1
where exists (select 1
from table2 t2
where t2.mesta_email = t1.mesta_email and t2.mesta_kod = t1.mesta_kod
) and
not exists (select 1
from table3 t3
where t3.mesta_email = t1.mesta_email and t3.mesta_kod = t1.mesta_kod
);
One advantage of exists/not exists over other approaches involves duplicates. If one of the tables (say table1) has not duplicates, but the others might, there is no need to remove duplicates in the resulting data set.

How to combine 2 columns from 2 tables and subtract duplicates

I have 2 tables t1 and t2. Each have a customer ID column. What I am looking for is to join the 2 columns and SUBTRACT the duplicates.
My EG:
Table1 and Table2 with the IDs for each
I have tried a union query. The result I am left with is ID = 1,2,3,4,5,6,7,8,9,10. Where, what I'm after is subtracting 1-5 from Table2 and the result = 6,7,8,9,10.
I hope that makes sense and that someone is able to help. Sorry if this is a bit too simple compared to what you're all used to.
In SQL Server you can use the EXCEPT operator:
select ID
from Table2
except
select ID
from Table1
Mysql does not support it though. Using a an in clause or a left join would work in both servers:
--Using In clause
SELECT ID
FROM Table2
WHERE ID NOT IN
(
SELECT ID
FROM Table1
);
--Using join
SELECT Table2.ID
FROM Table2
left join Table1
on Table2.ID = Table1.ID
where Table1.ID is null
Use left outer join
select * from t1 left outer join t2 on t1.customerid = t2.customerid