Creating a join where I pull a count from another table - mysql

I have a table with real estate agent's info and want to pull firstname, fullname, and email from rets_agents.
I want to then get a count of all of their sales from a different table called rets_property_res_mstr.
I created a query that doesn't work yet so I need some help.
SELECT r.firstname, r.fullname, r.email
from rets_agents r
LEFT JOIN rets_property_res_mstr
ON r.email = rets_property_res_mstr.ListAgentEmail
LIMIT 10;

I'm not sure how to get the count in this.

You seem to be looking for aggregation:
SELECT a.firstname, a.fullname, a.email, COUNT(p.ListAgentEmail) cnt
FROM rets_agents a
LEFT JOIN rets_property_res_mstr p ON r.email = p.ListAgentEmail
GROUP BY a.firstname, a.fullname, a.email
ORDER BY ?
LIMIT 10;
Note that, for a LIMIT clause to really make sense, you need a ORDER BY clause so you get a deterministic results (otherwise, it is undefined which records will be shown) - I added that to your query with a question mark that you should replace with the relevant column(s).

I would consider using a CTE for this:
WITH sales as (
SELECT ListAgentEmail, count(*) count_of_sales
FROM rets_property_res_mstr
GROUP BY ListAgentEmail
)
SELECT r.firstname, r.fullname, r.email, count_of_sales
from rets_agents r
LEFT JOIN sales
ON r.email = sales.ListAgentEmail
LIMIT 10;

Related

Getting the top sales

How to i get the top vendor for each country? I have this code and it shows the connection between the two tables, now I have to get the largest gmv per country.
Here is my working code:
SELECT DISTINCT a.country_name, b.vendor_name,
SUM(a.gmv_local) as total_gmw
from `my-project-67287.order1.order2`a
join `my-project-67287.vendor1.vendor2` b on a.vendor_id = b.id
group by a.country_name, b.vendor_name;
The top 3 should show this:
Assuming you can save that SELECT into a table called vendors, you need to use it as the subquery in the FROM clause.
You could use this:
SELECT vendors.country_name, vendors.vendor_name, MAX(vendors.total_gmw)
FROM
(
SELECT DISTINCT a.country_name, b.vendor_name,
SUM(a.gmv_local) as total_gmw
from `my-project-67287.order1.order2`a
join `my-project-67287.vendor1.vendor2` b on a.vendor_id = b.id
group by a.country_name, b.vendor_name
) AS vendors
GROUP BY vendors.country_name;
I must mention I have not tested your query, since I do not have your tables, so I assumed it's correct.
I only created the vendors table with the required fields and values from your picture. This should print:
SELECT odr.c_name,vdr.v_name,odr.gmv
FROM(
SELECT *
FROM(
SELECT c_name,v_id,gmv
FROM `order`
ORDER BY gmv DESC
)
GROUP BY c_name
)AS odr
LEFT JOIN vender AS vdr ON vdr.id = odr.v_id
GROUP BY odr.c_name
c_name short for country_name

Trying to get the 2 min(count()) with Ties

I allow myself to write a thread regarding a query I'm trying to make for hours now. I'm trying to get the name of the friend (friend.first_name) who refuses the most proposed dates for events.
To do this I'm counting the number of proposed date and ORDER BY ASC.
SELECT COUNT(*) 'NbrProposedDate', f.FIRST_NAME,
f.LAST_NAME, f.FRIEND_ID
FROM PROPOSES
NATURAL JOIN FRIEND f
GROUP BY f.FRIEND_ID
ORDER BY NbrProposedDate ASC
LIMIT 1;
However, this does not take into account TIES.
What I'm looking for is the following result :
Furthermore, I've seen something with FETCH FIRST 1 ROW WITH TIES, however it does not seem to work with MySQL (getting SQL syntax issue).
Finally, I've had found an alternative using a function :
-- Find Minimum Count
SELECT MIN(cnt) INTO #min FROM (SELECT COUNT(*) cnt FROM PROPOSES NATURAL JOIN FRIEND f GROUP BY f.FRIEND_ID) t;
-- Show Friends with minimum count
DROP VIEW IF EXISTS troublemaker;
CREATE VIEW troublemaker AS
SELECT FIRST_NAME, LAST_NAME
FROM PROPOSES p
JOIN (SELECT FRIEND.FRIEND_ID
FROM PROPOSES
NATURAL JOIN FRIEND
GROUP BY FRIEND.FRIEND_ID
HAVING COUNT(*) = #min) t
ON p.FRIEND_ID = t.FRIEND_ID
JOIN FRIEND ON t.FRIEND_ID = FRIEND.FRIEND_ID
ORDER BY p.FRIEND_ID ASC;
However, the issue is that, I need to put this into a view, but "View's SELECT contains a variable or parameter".
Therefore, I'm looking for another alternative or a solution to fix this issue.
P.S. : here is an MLD :
View is not required, a query result could be used as subquery
SELECT
COUNT(*) NbrProposedDate,
MAX(f.FIRST_NAME) FIRST_NAME,
MAX(f.LAST_NAME) LAST_NAME,
f.FRIEND_ID
FROM PROPOSES
NATURAL JOIN FRIEND f
GROUP BY f.FRIEND_ID
HAVING COUNT(*) = (
SELECT COUNT(*)
FROM PROPOSES
NATURAL JOIN FRIEND f
GROUP BY f.FRIEND_ID
ORDER BY COUNT(*)
LIMIT 1
)
On MySQL 8+, it can also use RANK()
WITH ranks AS (
SELECT
COUNT(*) NbrProposedDate,
MAX(f.FIRST_NAME) FIRST_NAME,
MAX(f.LAST_NAME) LAST_NAME,
f.FRIEND_ID,
RANK() OVER (ORDER BY COUNT(*) ASC) rk
FROM PROPOSES
NATURAL JOIN FRIEND f
GROUP BY f.FRIEND_ID
)
SELECT * FROM ranks WHERE rk = 1

mysql avg function not returning all records

I am using following query
select
*,
dealer.id As dealerID,
services.id as serviceID
from services
LEFT JOIN dealer
on services.dealer=dealer.id
LEFT JOIN reviews
ON reviews.dealer_id=dealer.id
where services.brand_id = '9' and
services.model_id='107' and
services.petrol > 0
ORDER BY services.total asc ,
AVG(reviews.rating) desc
I have 6 records and it should display 6 records instead its displaying only 1. When i remove AVG(reviews.rating) desc. It display all records.
mysql tables are
services
dealer
brand_id
model_id
petrol
id
total
dealer
id
name
reviews
id
dealer_id
rating
I am not sure where i am doing mistake. If some can help.
avg() is an aggregation function. That is, it takes data from multiple rows and summarizes it.
Without a group by, the query is an aggregation query over all the data. Such a query always returns exactly one row.
Most databases would return an error when you use select *, use an aggregation function, and have no group by. MySQL has a (mis)feature where this syntax is allowed (although on the newest versions, the default settings disallow this).
I'm not sure what you are trying to do, but avg() doesn't make sense in this context. Perhaps this does what you want:
ORDER BY services.total asc, reviews.rating desc
As already mentioned AVG() is aggregate ftn, so I have changed the desc of your order by to include to select the average values.
For future reference:
Providing snippets of raw data also helps. Creating an sql fiddle helps even more
select
*,
dealer.id As dealerID,
services.id as serviceID
from services
LEFT JOIN dealer
on services.dealer=dealer.id
LEFT JOIN reviews
ON reviews.dealer_id=dealer.id
where services.brand_id = '9' and
services.model_id='107' and
services.petrol > 0
ORDER BY services.total asc ,
(SELECT AVG(r2.rating) FROM reviews r2 RIGHT JOIN ON r2.dealer_id=dealer.id) desc
You might try:
SELECT
*,
AVG(c.rating) AS `avg__rating`,
b.id AS dealerID,
a.id AS serviceID
FROM services a
LEFT JOIN dealer b
on a.dealer = b.id
LEFT JOIN reviews c
ON c.dealer_id = b.id
WHERE a.brand_id = '9' and
a.model_id='107' and
a.petrol > 0
GROUP BY a.dealer, a.brand_id, a.model_id, a.petrol, a.id, a.total
ORDER BY a.total asc,
AVG(c.rating) desc
This adds a GROUP BY on the columns in your services table so you will get one row per services/dealer.

Wrong use of inner join function / group function?

I have the following problem with my query:
I have two tables:
Customer
Subscriber
linked together by customer.id=subscriber.customer_id
in the subscriber table, I have records with id_customer=0 (these are email records, that do not have a full customer account)
Now i want to show how many customers I have per day, and how many subscribers with id_customer, and how many subscribers WITH id_customer=0 (emailonlies i call them)
Somehow, i cannot manage to get those emailonlies.
Perhaps it has something to do with not using the right join type.
When i use left join, i get the right amount of customers, but not the right amount of emailonlies. When I use inner join i get the wrong amount of customers. Am i using the group function correctly? i think it has something to do with that.
THIS IS MY QUERY:
` SELECT DATE(c.date_register),
COUNT(DISTINCT c.id) AS newcustomers,
COUNT(DISTINCT s.customer_id) AS newsubscribedcustomers,
COUNT(DISTINCT s.subscriber_id AND s.customer_id=0) AS emailonlies
FROM customer c
LEFT JOIN subscriber s ON s.customer_id=c.id
GROUP BY DATE(c.date_register)
ORDER BY DATE(c.date_register) DESC
LIMIT 10
;`
I'm not entirely sure, but I think in DISTINCT s.subscriber_id AND s.customer_id=0, it runs the AND before the DISTINCT, so the DISTINCT only ever sees true and false.
Why don't you just take
COUNT(DISTINCT s.subscriber_id) - (COUNT(DISTINCT s.customer_id) - 1)?
(The -1 is there because DISTINCT s.customer_id will count 0.)
Got it, only risk is that i get no email onlies if there are no customers on this day, becuase of the left join. But this one works:
SELECT customers.regdatum,customers.customersqty,subscribers.emailonlies
FROM (
(SELECT DATE(c.date_register) AS regdatum,COUNT(DISTINCT c.id) AS customersqty
FROM customer c
GROUP BY DATE(c.date_register)
) AS customers
LEFT JOIN
(SELECT DATE(s.added) AS voegdatum,COUNT(DISTINCT s.subscriber_id) AS emailonlies
FROM subscriber s
WHERE s.customer_id=0
GROUP BY DATE(s.added)
) AS subscribers
ON customers.regdatum=subscribers.voegdatum
)
ORDER BY customers.regdatum DESC
;

Count repeating names in table

I have two tables: Customer and ParkingTransaction. I want to show the top 10 customers who use the lot most often. 'CustomerKey' in the ParkingTrasaction table is the FK that connects ParkingTransaction to Customer. I have written the following code which counts the most used CustomerKey in the ParkingTransaction table, and it works fine...
SELECT TOP 10 CustomerKey
, count(*) as 'Usage'
FROM ParkingTransaction
GROUP BY CustomerKey
HAVING (count(CustomerKey) > 0)
ORDER BY 'Usage' DESC
This is my output
Output
The problem I am facing is this: I want to pull the FirstName and LastName fields from the Customer table, instead of sorting by just the CustomerKey. I have messed around with JOINS, but haven't come up with a solution yet.
Thanks!
MySQL uses LIMIT not TOP.
SELECT a.FirstName, a.LastName,
COUNT(*) as `Usage`
FROM Customer a
INNER JOIN ParkingTransaction b
ON a.CustomerKey = b.CustomerKey
GROUP BY a.FirstName, a.LastName
ORDER BY `Usage` DESC
LIMIT 10
since the query is using INNER JOIN, HAVING COUNT(*) > 0 is unneccessary in this case.
Here is one way:
SELECT CustomerKey, c.firstname, c.lastname, count(*) as 'Usage'
FROM ParkingTransaction pt join
customer c
on pt.customerkey = c.customerkey
GROUP BY pt.CustomerKey, c.firstname, c.lastname,
ORDER BY 'Usage' DESC
limit 10