Join of three different mysql queries tables - mysql

I want to join three different queries.
Here are my queries
Query1:
SELECT u.user_name,u.first_name
FROM users u join users_cstm uc on u.id=uc.id_c
WHERE u.deleted=0?
Query2:
SELECT l.assigned_user_id,count(*) AS lead_count
FROM lead l GROUP BY l.assigned_user_id?
Query3:
SELECT l.assigned_user_id,AVG(DATEDIFF(l.date_modified,l.date_entered)) AS avgdays
FROM leads l GROUP BY l.assigned_user_id?
and so on.
This is the result I am looking for user_name, first_name,lead_count,avgdays. from three tables.
BigQuery join of three tables
I have tried my solution from the above link. But I didn't get the result.

Try below query:-
SELECT u.user_name,u.first_name,
lead_table.lead_count,lead_table.avgdays
FROM users u join users_cstm uc on u.id=uc.id_c
left join
(SELECT l.assigned_user_id,
AVG(l.date_modified) AS avgdays,
count(*) AS lead_count
FROM leads l GROUP BY l.assigned_user_id) lead_table
on u.id=lead_table.assigned_user_id
WHERE u.deleted=0;

Try this:
SELECT id,user_name,first_name,lead_count,avgdays from
(SELECT id,user_name,first_name,lead_count from
(SELECT u.id,u.user_name,u.first_name FROM users u,users_cstm uc where u.id=uc.id_c and u.deleted=0) as a
LEFT JOIN
(SELECT l.assigned_user_id,count(*) AS lead_count FROM lead l GROUP BY l.assigned_user_id) as b
on a.id = b.assigned_user_id) as a
LEFT JOIN
(SELECT l.assigned_user_id,AVG(DATEDIFF(l.date_modified,l.date_entered)) AS avgdays
FROM leads l GROUP BY l.assigned_user_id) as b
on a.id = b.assigned_user_id

Related

Left join Count disturbing left join SUM

When i added a left join for getting count of foreign table, its multiply my sum value of other left join table with the count, also I cant use distinct sum here as two values can be same:
SELECT c.id as company_id, SUM(ct.amount) as total_billed, count(l.id) as load_count
FROM tbl_companies c
LEFT JOIN tbl_company_transactions ct ON c.id = ct.company_id
LEFT JOIN tbl_loads l ON c.id = l.company_id
GROUP BY c.id;
You need to pre-aggregate the data:
SELECT c.id as company_id, ct.total_billed,
l.load_count
FROM tbl_companies c LEFT JOIN
(SELECT ct.company_id, SUM(ct.amount) as total_billed
FROM tbl_company_transactions ct
GROUP BY ct.company_id
) ct
ON c.id = ct.company_id LEFT JOIN
(SELECT l.company_id, COUNT(*) as load_count
FROM tbl_loads l
GROUP BY l.company_id
) l
ON c.id = l.company_id;
As you have observed, the JOIN multiplies the number of rows and affects the aggregations.
You could isolate aggregate statistics and join results afterwards.
WITH
tranStats AS (
SELECT company_id, SUM(amount) AS total_billed
FROM tbl_company_transactions
GROUP BY company_id
),
loadStats AS (
SELECT company_id, COUNT(1) AS load_count
FROM tbl_loads
GROUP BY company_id
)
SELECT id, total_billed, load_count
FROM tbl_companies c
LEFT JOIN tranStats t ON t.company_id = c.id
LEFT JOIN loadStats l ON l.company_id = c.id
Gordon's answer is more scalable but for this specific query you only need one subquery — which may also offer a performance boost since joins on the pre-aggregated data may not be able to use indexes.
SELECT c.id as company_id, SUM(ct.amount) as total_billed, l.load_count
FROM tbl_companies c
LEFT JOIN tbl_company_transactions ct ON c.id = ct.company_id
LEFT JOIN (
SELECT company_id, count(*) as load_count
FROM tbl_loads
GROUP BY company_id
) l ON c.id = l.company_id
GROUP BY c.id;
The important thing to grasp is that if you need results of an aggregate function like SUM() or COUNT(), you need to be careful when you perform more than one join with multiple rows.

MYSQL: Handling Multiple LEFT JOINS

I have a query with one LEFT JOIN that works fine. When I add a second LEFT JOIN to a table with multiple records per field in the first table, however, I am getting the product of the results in the two tables ie books x publishers returned. How can I prevent this from happening?
SELECT a.*,b.*,p.*, group_concat(b.id as `bids`)
FROM authors `a`
LEFT JOIN books `b`
ON b.authorid = a.id
LEFT JOIN publishers `p`
on p.authorid = a.id
GROUP by a.id
EDIT:
Figured it out. The way to do this is to use subqueries as in this answer:
SELECT u.id
, u.account_balance
, g.grocery_visits
, f.fishmarket_visits
FROM users u
LEFT JOIN (
SELECT user_id, count(*) AS grocery_visits
FROM grocery
GROUP BY user_id
) g ON g.user_id = u.id
LEFT JOIN (
SELECT user_id, count(*) AS fishmarket_visits
FROM fishmarket
GROUP BY user_id
) f ON f.user_id = u.id
ORDER BY u.id;
If you do multiple LEFT Joins, your query will return a cartesian product of the results. To avoid this and get only one copy of fields you desire, do a subquery for each table you wish to join as below. Hope this helps someone in the future.
SELECT u.id
, u.account_balance
, g.grocery_visits
, f.fishmarket_visits
FROM users u
LEFT JOIN (
SELECT user_id, count(*) AS grocery_visits
FROM grocery
GROUP BY user_id
) g ON g.user_id = u.id
LEFT JOIN (
SELECT user_id, count(*) AS fishmarket_visits
FROM fishmarket
GROUP BY user_id
) f ON f.user_id = u.id
ORDER BY u.id;

use 2 left join can't work but separately can get results

I have three tables, company, user and share. I want to count one company's user and share, they are not relevant.
There may be a row that has share value but not user value. so I used left join, I can get results separately, but it doesn't work together.
Here is my query:
SELECT c.name, count(u.company_id), count(s.company_id)
FROM company c
LEFT JOIN user u
ON c.id=u.company_id and u.company_id=337
WHERE u.company_id is NOT NULL
LEFT JOIN share s
ON c.id=s.id AND s.company_id=337
WHERE s.company_id is NOT NULL
You need to do at least one of the counts in a subquery. Otherwise, both counts will be the same, since you're just counting the rows in the resulting cross product.
SELECT c.name, user_count, share_count
FROM company AS c
JOIN (SELECT company_id, COUNT(*) AS user_count
FROM users
GROUP BY company_id) AS u
ON u.company_id = c.id
JOIN (SELECT company_id, COUNT(*) AS share_count
FROM share
GROUP BY company_id) AS s
ON s.company_id = c.id
WHERE c.company_id = 337
Another option is to count the distinct primary keys of the tables you're joining with:
SELECT c.name, COUNT(DISTINCT u.id) AS user_count, COUNT(DISTINCT s.id) AS share_count
FROM company AS c
JOIN users AS u on u.company_id = c.id
JOIN share AS s ON s.company_id = c.id
WHERE c.company_id = 337
Your code looks okay, except for the extra WHERE clause. However, you probably want COUNT(DISTINCT), because the two counts will return the same value:
SELECT c.name, count(distinct u.company_id), count(distinct s.company_id)
FROM company c LEFT JOIN
user u
ON c.id = u.company_id and u.company_id=337 LEFT JOIN
share s
ON c.id = s.id AND s.company_id=337
WHERE s.company_id is NOT NULL AND u.company_id IS NOT NULL;

Any way to group the result of a DISTINCT and get the COUNT of the rows grouped correctly?

I have this query:
SELECT DISTINCT w.buyer_id, u.username, a.cb_id
FROM winners AS w
INNER JOIN auctions AS a ON w.auction_id=a.auction_id AND a.cb_id > 0 AND a.category_id=1922
INNER JOIN users AS u ON w.buyer_id=u.user_id
So basically I am trying to find out how many unique entries each w.buyer_id has been involved in with regards to a.cb_id.
So to do that I ran the above query and I get a row by row result, which is good as it shows all the unique values; so I can see that user A has 14 rows (14 unique CB ID's they are involved in) and user B may have 5 rows.
So I want to make it so I can get a record set with an output of:
w.buyer_id,u.username,count
I tried the below:
SELECT DISTINCT w.buyer_id, u.username, a.cb_id, COUNT(*) AS unique_spots
FROM winners AS w
INNER JOIN auctions AS a ON w.auction_id=a.auction_id AND a.cb_id > 0 AND a.category_id=1922
INNER JOIN users AS u ON w.buyer_id=u.user_id
GROUP BY w.buyer_id
LIMIT 5000;
...but it returns the COUNT as if I didn't even apply a DISTINCT to the record set.
What am I doing wrong here?
How about just writing a query to do what you want directly?
SELECT w.buyer_id, COUNT(DISTINCT a.cb_id)
FROM winners w INNER JOIN
auctions a
ON w.auction_id = a.auction_id AND a.cb_id > 0 AND
a.category_id = 1922 INNER JOIN
users u ON w.buyer_id = u.user_id
GROUP BY w.buyer_id;
The join to users seems superfluous:
SELECT w.buyer_id, COUNT(DISTINCT a.cb_id)
FROM winners w INNER JOIN
auctions a
ON w.auction_id = a.auction_id AND a.cb_id > 0 AND
a.category_id = 1922
GROUP BY w.buyer_id;
Have you tried this:
SELECT w.buyer_id, u.username, a.cb_id, COUNT(*) AS unique_spots
FROM winners AS w
INNER JOIN auctions AS a ON w.auction_id=a.auction_id AND a.cb_id > 0 AND a.category_id=1922
INNER JOIN users AS u ON w.buyer_id=u.user_id
GROUP BY w.buyer_id, u.username, a.cb_id
LIMIT 5000;

mysql join count lines in third table

I have three mySQL-tables like this:
client network activities
\_id \_id \_id
\_name \_name \_client_id
\_[...] \[...] \_[...]
\_network_id
Now I want to have the following result:
client.*, network.name, number_of_activities_for_each_client
Actually I have this select-statement:
select client.*, network.name
from client
left join network
on client.network_id = network.id
How do I extend the statement? I would also like to see all clients.
SELECT c.*, n.name, COUNT(a.id) number_of_activities_for_each_client
FROM clients c
LEFT JOIN network n
ON n.id = c.network_id
LEFT JOIN activities a
ON a.client_id = c.id
GROUP BY c.id