inner join to get row with max column value - mysql

I have been trying to get the value of rows where the column value is max.
but it's somehow not working. please help out a bit.
Let me explain the problem
table 1 name = agency
columns agency_id, agency_name
table 2 name = client
columns client_name, total_bill, agency_id
what i want to get is the client name, agency name and total_bill of the row
for which total_bill value is maximum.
here's the query I was using
SELECT a.agency_name
FROM agency a
INNER JOIN (SELECT agency_id, client_name, MAX(total_bill) total_bill FROM client GROUP BY agency_id ) c
ON a.agency_id = c.agency_id;
could you tell me where I am going wrong with this?
I am getting this error -
Expression #2 of SELECT list is not in GROUP BY clause and contains
nonaggregated column 'agency-app.client.client_name' which is not
functionally dependent on columns in GROUP BY clause; this is incompatible
with sql_mode=only_full_group_by
do let me know how to fix this.

If you want the overall top customer, you can just join, order and limit:
select
a.agency_name,
c.client_name,
c.total_bill
from agencies a
inner join clients c on c.agency_id = a.agency_id
order by c.total_bill desc
limit 1

Try this query:
SELECT client.name, agency.name, client.total_bill
FROM agency, client
WHERE agency.agency_id=client.agency_id
AND client.total_bill=(SELECT MAX(total_bill) FROM client)

Related

How to get data based on row count in MySQL?

I am working on a project where I have to fetch data from database if the row count is greater than zero then show it otherwise don't. But my query returning all rows.
This is My Query
SELECT
d.id,
d.district,
(
SELECT
COUNT(a.district_id)
FROM
ambulance AS a
WHERE
a.district_id = d.id
) AS total
FROM
district d
ORDER BY
total
DESC
That is okay, but I added a WHERE clause with my query witch is,
WHERE total > 0
But I am having a sql error Unknown column 'total' in 'where clause'
Now my question is, how can I achieve a result with WHERE total > 0, do I have to type something else in the place of total? What is the proper way to add this WHERE clause in my query.
MySQL extends the use of the HAVING clause, so it can be used in non-aggregation queries. This allows you to use an alias:
SELECT d.id, d.district,
(SELECT COUNT(*)
FROM ambulance a
WHERE a.district_id = d.id
) AS total
FROM district d
HAVING total > 0
ORDER BY total DESC;
This logic would more colloquially be written using an inner join:
select d.id, d.district, count(*) as total
from district d join
ambulance a
on a.district_id = d.id
group by d.id, d.district
order by total desc;
The join requires that there be at least one match.

Can't GROUP BY with first unique item in MYSQL

I have two MySQL tables:
product
photo
Then I do INNER JOIN
SELECT *
FROM product
INNER JOIN photo
ON product.productID = photo.productID
But I need only one raw per unique product ID
If I try:
SELECT *
FROM product
INNER JOIN photo
ON product.productID = photo.productID
ORDER BY product.productID
It returns error
Expression #38 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'photo.photoID' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
The problem is photoID column. There are few photos per one product, but I need table with only first photo per product.
Can I do it with MYSQL tools like WHERE for example?
Thanks!
When you use Aggregate function clause,you need to use GROUP BY on no-Aggregate column.
Making a subquery to find the MIN photoID. then JOIN on another subquery
You can try this.
SELECT p.*,T.* FROM
(
SELECT productID,MIN(photoID) 'photoID'
FROM photo
GROUP BY productID
) T
INNER JOIN (
SELECT DISTINCT productID,name
FROM product
) p ON p.productID = T.productID
sqlfiddle : http://sqlfiddle.com/#!9/97a87d/12

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.

Get a row which has the maximum id

Problem in simple words, 1st must be left joined to the 2nd table where the record is latest. So, I use an approach of using function MAX()
Currently I have 2 tables.
matches
matches_payments
|
Now I want to join the second table to first one using MAX(id) on matches_payments
Desired result
but I am not getting desired result due to greatest-n-per-group problem.
Query
SELECT matches.id, mp.*
FROM matches
LEFT JOIN (SELECT
MAX(id) AS id,
match_id
paymentStatus
FROM matches_payments
GROUP BY match_id) AS mp ON mp.id = matches.id;
Desired result is not produced due to : Stackoverflow Question
When using this feature, all rows in each group should have the same values for the columns that are ommitted from the GROUP BY part. The server is free to return any value from the group, so the results are indeterminate unless all values are the same.
FROM MySQL Dev
PS : I know the tables are poorly designed. It is not my work as the last developer did those.
You need two joins. You need a self-join of the matches_payments table to get the row with the highest ID for each match_id, as shown in SQL Select only rows with Max Value on a Column. Then you LEFT JOIN this to matches to combine the two tables:
SELECT m.*, mp.paymentStatus, mp.paymentAmount
FROM matches AS m
LEFT JOIN (
SELECT mp1.*
FROM matches_payments AS mp1
JOIN (SELECT match_id, MAX(id) AS id
FROM matches_payments
GROUP BY match_id) AS mp2
ON mp1.match_id = mp2.match_id AND mp1.id = mp2.id
) AS mp ON mp.match_id = m.id

Filter query by ID

I'm trying to retrieve all the product information, filtering by product category id. The result should be hundreds of products but only returns 5 items. Whats wrong with my query?
SELECT product.id_product,
product.reference,
product.price,
product.active,
product.quantity,
product.id_category_default,
lang.name AS product_name,
lang.description,
lang.link_rewrite AS product_link_rewrite,
category.name AS category_name,
category.link_rewrite AS category_link_rewrite,
image.id_image,
product.id_manufacturer,
discount.reduction,
manufacturer.name AS manufacturer_name
FROM ps_product product
LEFT JOIN ps_specific_price discount ON discount.id_product=product.id_product
LEFT JOIN ps_product_lang lang ON lang.id_product=product.id_product
LEFT JOIN ps_category_lang category ON category.id_category=product.id_category_default
LEFT JOIN ps_image image ON image.id_product=product.id_product
LEFT JOIN ps_manufacturer manufacturer ON manufacturer.id_manufacturer=product.id_manufacturer
WHERE product.active=1
AND product.quantity>=1
AND product.id_category_default IN
(
4,5,6,65,66,90,91,53,54,48,49,50,55,62,67,68,71,19,82,88,89,87,22,24,26,74,
76,77,28,78,79,97,98,99,93,96,35,36,38,39,100
)
GROUP BY product.id_product ASC
Perhaps something as simple as:
GROUP BY product.id_product ASC
needs to be:
ORDER BY product.id_product ASC
mySQL extends the group by clause so that any columns not in the group by may get an indeterminate value.
If ONLY_FULL_GROUP_BY is disabled, a MySQL extension to the standard SQL use of GROUP BY permits the select list, HAVING condition, or ORDER BY list to refer to nonaggregated columns even if the columns are not functionally dependent on GROUP BY columns. ... The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate, which is probably not what you want.
Options:
change group by to order by
add all columns to the group by
don't use group by at all.