MYSQL SUM and INNER JOIN - mysql

I want to have the name in the first colomn but i get an error. When i Let P.name out, the query works but I can't see the player name.
Right now I have the following query:
SELECT P.Name, P.Playernr, SUM (F.Amount)
FROM FINES F
INNER JOIN PLAYERS P
ON F.Playernr = P.Playernr
GROUP BY P.Playernr
Thanks in advance for help
Onno

You should add it to the GROUP BY clause.
SELECT P.Name, P.Playernr, SUM (F.Amount)
FROM FINES F
INNER JOIN PLAYERS P
ON F.Playernr = P.Playernr
GROUP BY P.Name,P.Playernr

Try this:
SELECT MAX(P.Name) as Name, P.Playernr, SUM (F.Amount)
FROM FINES F
INNER JOIN PLAYERS P
ON F.Playernr = P.Playernr
GROUP BY P.Playernr
or add P.Name to the Group BY
SELECT P.Name, P.Playernr, SUM (F.Amount)
FROM FINES F
INNER JOIN PLAYERS P
ON F.Playernr = P.Playernr
GROUP BY P.Name,P.Playernr

When GROUP BY used, only group by column and aggregation function can be projected. Remove P.Name in projection column or add P.Name in GROUP BY
SELECT P.Name, P.Playernr, SUM (F.Amount)
FROM FINES F
INNER JOIN PLAYERS P
ON F.Playernr = P.Playernr
GROUP BY P.Playernr, P.Name
In other RDBMS, your query produces error.
think about below data:
P.Playernr P.Name
A B
A C
A D
then, P.Name is not in GROUP BY, which value is produced in SELECT P.Playernr. so, you must use aggregation function or add P.Name in GROUP BY

Related

How to use subquery with inner join in MYSQL?

Do you guys have any idea how to combine this code using subquery. The code works fine but I don't know how to combine it as a one query
SELECT DATE_FORMAT(FROM_DAYS(DATEDIFF(now(),STR_TO_DATE(dob, '%c/%e/%Y'))), '%Y')+0 AS Age
FROM tblpatient
SELECT pres.*,
CONCAT(p.fname,' ',p.lname) AS pname,
p.gender,
p.address
FROM prescription pres
INNER JOIN tblpatient p
WHERE p.id = pres.patient_id
AND pres.id='$user_id' LIMIT 1"
I believe this is what you were expecting, merging both of your queries together.
SELECT pres.*,
CONCAT(p.fname,' ',p.lname) AS pname,
p.gender,
p.address,
DATE_FORMAT(FROM_DAYS(DATEDIFF(now(),STR_TO_DATE(p.dob, '%c/%e/%Y'))), '%Y')+0 AS Age
FROM prescription pres
INNER JOIN tblpatient p
WHERE p.id = pres.patient_id
AND pres.id='$user_id' LIMIT 1"

Multiple aggregate functions in SQL query

For this example I got 3 simple tables (Page, Subs and Followers):
For each page I need to know how many subs and followers it has.
My result is supposed to look like this:
I tried using the COUNT function in combination with a GROUP BY like this:
SELECT p.ID, COUNT(s.UID) AS SubCount, COUNT(f.UID) AS FollowCount
FROM page p, subs s, followers f
WHERE p.ID = s.ID AND p.ID = f.ID AND s.ID = f.ID
GROUP BY p.ID
Obviously this statement returns a wrong result.
My other attempt was using two different SELECT statements and then combining the two subresults into one table.
SELECT p.ID, COUNT(s.UID) AS SubCount FROM page p, subs s WHERE p.ID = s.ID GROUP BY p.ID
and
SELECT p.ID, COUNT(f.UID) AS FollowCount FROM page p, follow f WHERE p.ID = f.ID GROUP BY p.ID
I feel like there has to be a simpler / shorter way of doing it but I'm too unexperienced to find it.
Never use commas in the FROM clause. Always use proper, explicit, standard JOIN syntax.
Next, learn what COUNT() does. It counts the number of non-NULL values. So, your expressions are going to return the same value -- because f.UID and s.UID are never NULL (due to the JOIN conditions).
The issue is that the different dimensions are multiplying the amounts. A simple fix is to use COUNT(DISTINCT):
SELECT p.ID, COUNT(DISTINCT s.UID) AS SubCount, COUNT(DISTINCT f.UID) AS FollowCount
FROM page p JOIN
subs s
ON p.ID = s.ID JOIN
followers f
ON s.ID = f.ID
GROUP BY p.ID;
The inner joins are equivalent to the original query. You probably want left joins so you can get counts of zero:
SELECT p.ID, COUNT(DISTINCT s.UID) AS SubCount, COUNT(DISTINCT f.UID) AS FollowCount
FROM page p LEFT JOIN
subs s
ON p.ID = s.ID LEFT JOIN
followers f
ON p.ID = f.ID
GROUP BY p.ID;
Scalar subquery should work in this case.
SELECT p.id,
(SELECT Count(s_uid)
FROM subs s1
WHERE s1.s_id = p.id) AS cnt_subs,
(SELECT Count(f_uid)
FROM followers f1
WHERE f1.f_id = p.id) AS cnt_fol
FROM page p
GROUP BY p.id;

Using pseudonym in WHERE clause in MYSQL query

Please don't bite me for this, but I'm new to mysql and I have some problem with using pseudonym in WHERE clause. I thought that it is possible to use pseudonym for aggregate function, defined in the select statement.
Here is my query
SELECT a.name, s.name, COUNT(e.id) as total FROM athletes a
INNER JOIN sports s on s.id = a.sport_id
INNER JOIN events e on s.id = e.sport_id
WHERE total >=2 GROUP BY a.name
But, I catch an error "Unknown column total in WHERE clause".
Could anyone tell me if it is right to do query like this?
You can not use alias in the where clause. You need to use that in having
SELECT
a.name,
s.name,
COUNT(e.id) as total FROM athletes a
INNER JOIN sports s on s.id = a.sport_id
INNER JOIN events e on s.id = e.sport_id
GROUP BY a.name having total >=2
Instead of WHERE total >=2 you can use HAVING (total >= 2 )
HAVING:
SELECT a.name, s.name, COUNT(e.id) as total
FROM athletes a
INNER JOIN sports s on s.id = a.sport_id
INNER JOIN events e on s.id = e.sport_id
GROUP BY a.name, s.name
HAVING (total >= 2 );
Yo can not use an column alias in where clause. you have to use the expression COUNT(e.id) in where clasue or you can use the alias in a having clause:
SELECT a.name, s.name, COUNT(e.id) as total FROM athletes a INNER JOIN sports s on s.id = a.sport_id INNER JOIN events e on s.id = e.sport_id WHERE COUNT(e.id)>=2 GROUP BY a.name
or
SELECT a.name, s.name, COUNT(e.id) as total FROM athletes a INNER JOIN sports s on s.id = a.sport_id INNER JOIN events e on s.id = e.sport_id having total>=2 GROUP BY a.name

MySQL: Select multiple records with comma separated values

I have three tables: store_products, store_orders and store_orders_products. store_products contains all of the products, store_orders contains the order information, and store_orders_products contains each individual product in that order.
I'm building an Orders page that will list each order placed. It will have the username of the person who placed the order, the date, the total amount and the name of each product.
This query gets me everything I want, except it returns only ONE product name. I want to have each product in a comma separated string. I've tried subqueries, COALESCE, CONCAT, IN(), etc, but I'm not getting the results I want.
SELECT
o.id AS order_id
, o.order_total
, o.created_at
, u.username
, u.avatar
, sp.name
FROM store_orders o
JOIN store_orders_contents c ON o.id=c.oid
JOIN store_products p ON p.id=c.pid
JOIN users u ON u.id=o.consumer_uid
JOIN store_products sp ON sp.id=c.pid
WHERE p.uid=3
GROUP BY order_id
I think you want group_concat():
SELECT o.id AS order_id, o.order_total, o.created_at, u.username, u.avatar,
group_concat(sp.name )
FROM store_orders o JOIN
store_orders_contents c
ON o.id = c.oid JOIN
store_products p
ON p.id = c.pid JOIN
users u
ON u.id = o.consumer_uid JOIN
store_products sp
ON sp.id = c.pid
WHERE p.uid = 3
GROUP BY order_id;
I don't understand why you are joining to store_products twice, but I assume you know what you are doing with the joins.

MySQL Subquery Question

I have a query to pull a total number for a given publisher ID. I'd like to use it as a subquery so I can iterate over all publisher IDs.
My working query for a given ID is:
SELECT SUM( d.our_cost )
FROM articles a
CROSS JOIN domains d ON a.domain_id = d.id
AND d.publisher_id = '1094'
I'd like to pull this figure for all ID's in publisher p table where d.publisher_id = p.id
So far I've tried the following to no avail:
SELECT p.id, p.contact_name, p.contact_email,
(SELECT SUM(d.our_cost)
FROM articles a
CROSS JOIN domains d ON a.domain_id = d.id and d.publisher_id = p.id) total
FROM publishers p
The specific error I'm getting is: Unknown column 'p.id' in 'on clause'
I think you should modify your query and put the subquery in the from clause, something like this:
SELECT p.id, p.contact_name, p.contact_email, total.total_cost
FROM
(
SELECT SUM(d.our_cost) as total_cost, d.publisher_id
FROM articles a CROSS JOIN domains d ON a.domain_id = d.id ) total
JOIN publishers p on total.publisher_id = p.id
I'm assuming you've gotten an error about your syntax, try:
SELECT p.id, p.contact_name, p.contact_email, SUM(d.our_cost) as total
FROM articles a
CROSS JOIN domains d ON a.domain_id = d.id
JOIN publishers p ON d.publisher_id = p.id
seems like a group by would be handy here instead
Also it seems like you dont need articles table at all (unless you have additional business rules)
SELECT p.id, p.contact_name, p.contact_email, IFNULL(SUM(d.our_cost),0) AS total
FROM publishers p
LEFT JOIN domains d ON d.publisher_id = p.id
GROUP BY p.id