How can i join the following SQL query?
SELECT SUM( payments.amount ) , SUM( payments.balance ) , records.recordID, records.record
FROM fees AS payments
INNER JOIN recordtype AS records ON payments.referenceID = records.recordID
the above query is giving the following error
MySQL said: Documentation
1140 - Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
My Expectation results would like each recordID to show balance and amount it has.
Thank and Regards, all Suggestions & Questions are welcome
SELECT SUM( payments.amount ) , SUM( payments.balance ) , records.recordID, records.record
FROM fees AS payments INNER JOIN recordtype AS records
ON payments.referenceID = records.recordID
GROUP BY records.recordID, records.record
When you have used an aggregate function in your SELECT statement you have to tell sql how to do the aggregates on that column by using GROUP BY clause,
Simple rule of thumb, When you have used an aggregate function (COUNT,MAX, MIN, SUM, AVG) in a SELECT statement any other columns that are in that SELECT and are not contained in any aggregate function MUST come in GROUP BY clause of that statement.
Your SQL statemant won't work because you have not made it clear what to count. If you use sum() or max() or min() or something like that, you have to use a group by in your statement. So, e.g. if you want to calculate the sum of the amount your customers purchase in your shop use something like this:
SELECT SUM( payments.amount )
FROM payments
inner join customer on payments.customer_id = customer.id
GROUP BY customer.id
And, if you wan't to check only one customer you have to use the SQL clouse "haveing". Where won't work in that case.
Related
I have a PHP/MySQL application
The application uses a query to get the values of a table leads, with 2 sub-queries to return the SUM and COUNT of values in a second table refunds
The 2 tables are linked with a foreign key lead_id
SELECT l.*,
IFNULL(
(SELECT SUM(amount)
FROM refunds r
WHERE l.lead_id = r.lead_id),0) amount_refunded,
IFNULL(
(SELECT COUNT(*)
FROM refunds r
WHERE l.lead_id = r.lead_id),0) number_refunded
FROM leads l
I would like to increase the performance of this query.
My thought was to:
Combine the the 2 sub-queries into a single sub-query using CONCAT
with a pipe delimiter
Explode the returned string using PHP at the application level to
get the 2 values.
Example below:
SELECT l.*,
(SELECT CONCAT(IFNULL(COUNT(*),0),'|', IFNULL(SUM(amount),0))
FROM fee_refunds r
WHERE l.lead_id = r.lead_id) values_refunded
FROM fee_leads l
Then in the application, within the loop:
list($amount_refunded, $number_refunded) = explode('|', $row->values_refunded);
This approach works, however my questions are:
Is this bad form?
Is there any reason I should not do it this way?
Is there a better solution?
Use join!
SELECT l.*, r.amount_refunded, r.number_refunded
FROM leads l LEFT JOIN
(SELECT lead_id, COUNT(*) as number_refunded, SUM(amount) as amount_refunded
FROM refunds r
GROUP BY lead_id
) r
ON l.lead_id = r.lead_id;
You may find it faster, under some circumstances, to join before the aggregation.
We are working on a project for school and have a small issue with a query.
What we try to do is the following:
Select the education-unit(s) with the same version_vid and after that select the education-unit with the latest version_date.
But whatever we try, the education-unit with the lowest euid is returning.
We are using the Yii2 framework for this project, the ActiveQuery we use is:
EducationUnit::find()->groupBy('version_vid')->orderBy('version_date DESC');
SQL Fiddle:
http://sqlfiddle.com/#!9/9929d/2/0
Thanks in advance!
Maybe this can help you:
EducationUnit::find()
->from('select * from education_unit ORDER BY version_date DESC')
->groupBy('version_vid')
->all();
Wrap a select around your query, after that do the group by:
SELECT * FROM
( SELECT * FROM `education_unit` ORDER BY `version_date` DESC ) a
GROUP BY a.`version_vid`
Why it didn't work in your query is because SQL has an execution plan as below:
FROM clause
WHERE clause
GROUP BY clause
HAVING clause
SELECT clause
ORDER BY clause
The reason you are getting the lowesteuid is that the ORDER BY is applied after the GROUP BY and the GROUP BY is choosing arbitrary values from the group to return.
This is a classic top in group question and has been answered previously
I personally like the answer supplied by Bill Karwin which when applied to your situation becomes:
SELECT t.*
FROM table t
LEFT JOIN table t2
ON t2.version_vid = t.version_vid
AND t2.version_date > t.version_date
WHERE t2.version_vid IS NULL
Another common solution is:
SELECT t.*
FROM table t
JOIN (
SELECT version_id, MAX(version_date) version_date
FROM table
GROUP BY version_id
) t2
ON t2.version_id = t1.version_id
AND t2.version_date = t1.version_date
I have a problem with an SQL query. This is my first time using advanced SQL operations like this so it could be that I'm missing something basic. I am running this query:
SELECT countries.id,
countries.name,
AVG(users.points) AS average
FROM countries
LEFT JOIN users
ON countries.id = users.country
ORDER BY average DESC
This query is only returning 1 row and it's not following the ORDER BY because the returned value is . My aim with this is to get all the records in the Countries table and get the average of the points awarded to the users from each country. I want it to return those countries which do not have users assigned to them as well. I have done this in 2 queries and it worked but I thought that maybe I could do only one query. What am I missing?
It is only returning one row because it is an aggregation query without a group by. Perhaps you mean:
SELECT c.id, c.name, AVG(u.points) AS average
FROM countries c LEFT JOIN
users u
ON c.id = u.country
GROUP BY c.id, c.name
ORDER BY average DESC;
The AVG() makes this an aggregation query. Without the the group by, SQL interprets it as returning one row summarizing all the rows. MySQL supports an extension to the SQL standard where columns in the select do not have to be in the group by. In most databases, you query would return an error.
I need help with an advanced SQL-query (MSSQL 2000).
I have a table called Result that lists athletics 100 meter race-times. A runner can have several racetimes but I want to show only the best time from each runner.
The Result-table contains three columns, Result_id, athlete_id, result_time. So athlete_id must be unique when I list the values and result_time must be the fastest (lowest) value.
Any ideas?
In SQL Server 2000, you can't use windows functions. You can do this as follows:
select r.*
from result r join
(select athlete_id, min(result_time) as mintime
from result r
group by athlete_id
) rsum
on rsum.athlete_id = r.athlete_id and r.time = rsum.mintime
In more recent versions of SQL Server, you would use row_number().
If you simply need the fastest time for each athlete_id, do this:
select athelete_id, min(result_time) as FastestTime
from result
group by athelete_id
To show additional columns from the result table, you can join back to it like this:
select r.*
from result r
inner join (
select athelete_id, min(result_time) as FastestTime
from result
group by athelete_id
) rm on r.athelete_id = rm.athelete_id and r.result_time = rm.FastestTime
What you want is to use an aggregate function. in this case min() which will select the minumin data from all the rows that have the same data in the other selected columns. This means you also have to us the group by clause. The query below should give you the results you want.
Edit: If you need other columns, just bring them into the select clause, then add them to the group by clause like below:
select althlete_id, result_id, min(result_time) as result_time from result-table group by althlete_id, result_id
select althlete_id, result_id, min(result_time) as result_time, race_date from result-table group by althlete_id, race_date, result_id
Edit: You need to add all the columns into the group by that aren't part of an aggregate function. Aggregate functions are ones like min(), max(), avg() and so on.
Short answer: If you aren't putting a column in brackets, it probably has to be in the group by.
I have the following results for my database table:
The Query:
SELECT
service_titles.user_id, service_titles.slide_id, service_titles.name as title_name ,service_names.name as service_name
FROM service_names
INNER JOIN service_titles ON service_names.title_id = service_titles.id
So what needs to happen is:
If the user has 2 unique service titles, then the max number of service_names for that title will be 6
If the user has 1 service title, the the max number of service_names for that title will be 16
I will be using PHP for all of the coding, but I am wondering how I would go about this. I need a way to count how many unique service_titles there are for that user and slide, and then count how many service items there are for each title.
Thanks for any help!
SELECT COUNT(DISTINCT service_titles.name)
FROM service_names
INNER JOIN service_titles ON service_names.title_id = service_titles.id
GROUP BY service_titles.user_id, service_titles.slide_id
That'll get you the number of distinct title_names for each user_id/slide_id combo.
SELECT COUNT(DISTINCT service_names.name)
FROM service_names
INNER JOIN service_titles ON service_names.title_id = service_titles.id
GROUP BY service_titles.user_id, service_titles.slide_id
... and that's the number of distinct service_names for same. If you want both in one query, you can put both COUNTs together, since you're using the same GROUP BY regardless.
You could use a CASE statement within your query to change the max number of service_names.
See MySQL CASE statement reference
To do this in the SQL itself would be quicker than evaluating it in PHP.
To count how many distinct titles you can try:
SELECT user_id, COUNT(DISTINCT name)
FROM service_titles
GROUP BY user_id