Mysql error Invalid use of group function - mysql

select
c.investor_id as investorid,
i.name as investor_name,
inv_typ.name as type_of_investor,
(select count(*) from investor_users where user_id=iu.user_id) as num_of_investors,
(select count(*) from task_logs where campaign_id=c.id) as num_of_task_logs,
c.updated_at as updated_date,
c.call_date as calldate,
a.name as admin_name,
c.id as campaign_id
from
admins a,
investors i,
investor_types inv_typ,
campaigns c,
task_logs tl,
campaign_statuses cs,
investor_users iu
where
c.investor_id=i.id
and i.investor_type_id=inv_typ.id
and i.id=iu.investor_id
and c.campaign_status_id = cs.id
and c.assigned_to_admin_id = a.id
and c.campaign_type_id = 1
and c.campaign_status_id = (select id from campaign_statuses having id=c.campaign_status_id and cs.code ='CLOSED') and c.assigned_to_admin_id = 46
and tl.campaign_id = c.id and max((select task_logs.task_status_id from task_logs having task_logs.campaign_id = c.id)) = 9
order by c.call_date ASC

You have a max() in the where clause:
max((select task_logs.task_status_id
from task_logs
having task_logs.campaign_id = c.id)) = 9
That is an improper use of an aggregation function. Instead:
(select max(task_logs.task_status_id)
from task_logs
where task_logs.campaign_id = c.id) = 9
This glaring error was easy to spot, because it is so audacious. However, your query would benefit from the following:
Never use commas in the FROM clause. Always use proper explicit JOIN syntax. That is the proper way to express joins for two decades, so it is time for everyone to use it.
Use table aliases so queries are easier to write and to read.
Don't confuse the having clause with the where clause. That subquery should have used where.

Related

Same query different database different result

I try to change database from 'MySQL' to 'PostgreSQL' but i have problem some of my query
SELECT
SUM( CASE WHEN b.DISPLAYNAME IS NULL THEN 0 ELSE 1 END ) AS NUMMENUDETAIL,
A.DISPLAYNAME AS GROUPNAME,
b.displayname,
D.NAME,
min( A.ROLEID ) AS ROLEID
FROM
usermenu A
LEFT JOIN usermenu B ON A.ID = B.GROUPID,
userrole C,
position D,
positiondetail E
WHERE
( A.GROUPID IS NULL )
AND D.id = E.position_id
AND A.ROLEID = E.userrole_id
AND A.ROLEID = C.ID
AND B.ROLEID = E.userrole_id
AND B.ROLEID = C.ID
AND b.displayname = 'Transaction Listing Report'
GROUP BY
A.DISPLAYNAME,
b.displayname
LIMIT 10
i use this query into "MySQL" it pass
but when i use in "PostgreSQL" it error, They want my to GROUP BY d.name
then if i GROUP BY it may have different result
How can i fix this ?
This query does not comply with the SQL standard, so it is unsurprising that it does not work on all databases. The standard requires that all columns in the SELECT list that do not appear only inside aggregate functions must be in the GROUP BY clause.
You can have the same effect by using the (again, non-standard) DISTINCT ON clause in PostgreSQL.

Unknown column 'b.Hostname' in 'on clause'

I have the following MYSQL Query - trying to join 3 tables and find unique information(data)
SELECT a.LocationID, a.Model, a.SerialNum,a.Purpose, b.IP, a.Services,a.DeviceID, COUNT(a.Hostname)
FROM RefConnection.Equipment_Info a, RefConnection.Connections b, RefConnection.VM_Info c
JOIN Equipment_Info on b.Hostname = a.Hostname
WHERE a.Hostname = c.Hostname
AND b.status = a.Status
AND a.status = c.Status
GROUP BY a.LocationID, a.Model, a.SerialNum, a.Purpose, b.IP, a.Services, a.DeviceID
ORDER BY COUNT(b.Hostname)DESC;
This works with 2 tables :
SELECT d.locationID, d.Model, d.SerialNum, d.Status, da.IP, COUNT(d.HOSTNAME)
FROM RefConnection.Equipment_Info d, RefConnection.Connections da
WHERE d.Hostname = da.Hostname
AND d.Status = da.Status
Group By d.locationID, d.Model, d.locationID, d.Model, d.SerialNum, d.Status, da.IP
ORDER BY COUNT(da.Hostname) DESC;
Unknown column 'b.Hostname' in 'on clause'
Never use commas in the FROM clause. Always use proper, explicit, standard JOIN syntax.
FROM RefConnection.Equipment_Info a JOIN
RefConnection.Connections b
ON b.Hostname = a.Hostname AND
b.status = a.Status JOIN
RefConnection.VM_Info c
ON a.Hostname = c.Hostname AND
a.status = c.Status
Your problem is the scoping rules for identifiers. This does not work as you expect with commas -- yet another reason to avoid them.
I don't know what Equipment_Info is doing a second time in the query.
I would also strongly advise you to use meaningful table aliases, such as e, c, and i rather than arbitrary characters.

Trying to add one last SUM() column to my query in SQL Server 2008

I have the first query which is producing correct results. What I need is I need to add the sum of values as a last column grouped by surveyid. I can't insert Sum(c.value) into the first query because it is an aggregate function. I have the correct query as my second query below. I know there's pivot functionality but not sure if it can be used here. I do realize that there will be repetition but that's okay.
'first query
SELECT
A.PATIENTID, B.STUDENTNUMBER, c.surveyid,
convert(varchar, A.CreatedDate, 107),
C.QuestionID, C.Value, D.Question
FROM
dbo.Survey A, dbo.Patient B, [dbo].[SurveyQuestionAnswer] C, [dbo].[LookupQuestions] D
WHERE
A.PATIENTID = B.ID
and c.SurveyID = A.ID
and c.QuestionID = d.ID
and c.questionid <> 10
ORDER BY
A.PATIENTID
'second query
select
c.surveyid,SUM(c.value) as scores
from
dbo.SurveyQuestionAnswer c
group by
c.SurveyID
order by
SurveyID '---not important
You can use SUM if you add the OVER clause. In this case:
SELECT
A.PATIENTID, B.STUDENTNUMBER, c.surveyid,
convert(varchar, A.CreatedDate, 107),
C.QuestionID, C.Value, D.Question,
SUM(c.Value) OVER(PARTITION BY c.surveyid) scores
FROM
dbo.Survey A
INNER JOIN dbo.Patient B
ON A.PATIENTID = B.ID
INNER JOIN [dbo].[SurveyQuestionAnswer] C
ON c.SurveyID = A.ID
INNER JOIN [dbo].[LookupQuestions] D
ON c.QuestionID = d.ID
WHERE
c.questionid <> 10
ORDER BY
A.PATIENTID
You could use something like this:
SELECT
s.PATIENTID, p.STUDENTNUMBER, sqa.surveyid,
CONVERT(varchar, s.CreatedDate, 107),
sqa.QuestionID, sqa.Value, lq.Question,
Scores = (SELECT SUM(Value) FROM dbo.SurveyQuestionAnswer s2 WHERE s2.SurveyID = s.ID)
FROM
dbo.Survey s
INNER JOIN
dbo.Patient p ON s.PatientID = p.ID
INNER JOIN
[dbo].[SurveyQuestionAnswer] sqa ON sqa.SurveyID = s.ID
INNER JOIN
[dbo].[LookupQuestions] lq ON sqa.QuestionID = lq.ID
WHERE
sqa.questionid <> 10
ORDER BY
s.PATIENTID
By having a subquery with the SUM(...) you should be able to get that sum as a single value and you don't need to use any grouping function

how to simplify my sql query

I have this query, but it takes about 15 seconds to finish.. how can i simplyfy it to get same result in less time? my problem is that i need all of this data at ones.
SELECT * FROM (
SELECT c.client_id, c.client_name, c.client_bpm,
c.client_su_name, c.client_maxbpm, s.bpm,
s.timestamp, m.mesure_id, ms.currentT
FROM tbl_clients c, tbl_meting m, tbl_sensor_meting s,
tbl_magsens_meting ms
WHERE c.client_id = m.client_id
AND (m.mesure_id = s.id_mesure
OR m.mesure_id = ms.id_mesure)
AND m.live =1
ORDER BY s.timestamp DESC
) AS mesure
GROUP BY mesure.client_id
I think the problem may be the OR condition from your WHERE clause? You seem to be trying to join to one table or another, which you can't do. So I've replaced it with a LEFT JOIN, so in the event no related records exist nothing will be returned.
I also took out your GROUP BY, as I don't think it was required.
SELECT c.client_id, c.client_name, c.client_bpm,
c.client_su_name, c.client_maxbpm, s.bpm,
s.timestamp, m.mesure_id, ms.currentT
FROM tbl_clients c
JOIN tbl_meting m ON m.client_id = c.client_id
LEFT JOIN tbl_sensor_meting s ON s.id_mesure = m.mesure_id
LEFT JOIN tbl_magsens_meting ms ON ms.id_mesure = m.mesure_id
WHERE m.live = 1
ORDER BY s.timestamp DESC

MySQL sum of sub queries

I have quite a long query that is causing me some problems. For the first sub-query I keep getting the error: "MySQL server version for the right syntax to use near 'SELECT project.project_total_num_hours_quoted FROM project inner join time_recor' at line 5".
The subquery in question is:
sum(SELECT
project.project_total_num_hours_quoted
FROM
project inner join time_recording using(project_id)
WHERE
project.company_id = company.company_id
AND project_is_retainer != 1
AND time_recording.time_recording_event_start_datetime >= '2011-01-01' AND time_recording.time_recording_event_stop_datetime <= '2011-03-01'
group by project_id
) AS hours_quoted,
This returns a set of results. In the larger query I simply want to have the sum.
SELECT
SUM((unix_timestamp(time_recording.time_recording_event_stop_datetime)-unix_timestamp(time_recording.time_recording_event_start_datetime))/3600) AS total_time,
company.company_label,
sum(SELECT
project.project_total_num_hours_quoted
FROM
project inner join time_recording using(project_id)
WHERE
project.company_id = company.company_id
AND project_is_retainer != 1
AND time_recording.time_recording_event_start_datetime >= '2011-01-01' AND time_recording.time_recording_event_stop_datetime <= '2011-03-01'
group by project_id
) AS hours_quoted,
(SELECT SUM(project.project_total_num_hours_quoted)
FROM project
INNER JOIN time_recording ON project.project_id = time_recording.project_id
WHERE time_recording.time_recording_event_start_datetime>='2011-01-01'
AND project_is_retainer!=1
AND time_recording.time_recording_event_stop_datetime<='2011-03-01'
AND project.company_id!=1
) AS total_hours_quoted,
(
SELECT
SUM((unix_timestamp(time_recording.time_recording_event_stop_datetime)-unix_timestamp(time_recording.time_recording_event_start_datetime))/3600)
FROM time_recording
INNER JOIN project ON time_recording.project_id = project.project_id
WHERE project.company_id!=1
AND project_is_retainer!=1
AND time_recording.time_recording_event_start_datetime>='2011-01-01'
AND time_recording.time_recording_event_stop_datetime<='2011-03-01'
)
AS total_hours
FROM time_recording
INNER JOIN project ON time_recording.project_id = project.project_id
INNER JOIN company ON project.company_id = company.company_id
WHERE company.company_id!=1
AND project_is_retainer!=1
AND time_recording.time_recording_event_start_datetime>='2011-01-01'
AND time_recording.time_recording_event_stop_datetime<='2011-03-01'
GROUP BY company.company_id
ORDER BY total_time desc
LIMIT 7
In your first subquery, you don't need the group by if you sum it in the outer query. And you are missing the ON clause.
SELECT project.project_total_num_hours_quoted
FROM project inner join time_recording
ON project.id=time_recording.project_id
WHERE
project.company_id = company.company_id
AND project_is_retainer != 1
AND time_recording.time_recording_event_start_datetime >= '2011-01-01'
AND time_recording.time_recording_event_stop_datetime <= '2011-03-01'
I would strongly recommend scrapping this and starting again.
Several, if not all, the subselects could be merged into a single SELECT statement. The outer SELECT is an aggregate operation which selects non-aggregated values not included in the GROUP BY clause. MySQL does not optimize push-predicates. And you've got redundant joins in the query.