Unexpected result using AVG() on negative floats in mySQL - mysql

This query
SELECT *
FROM `rounds`
WHERE `user` = 18956 AND `handicapDifferential` IS NOT NULL
ORDER BY `handicapDifferential` DESC, `date` DESC
LIMIT 0, 2
Gives expected result of two rows with -1.4 and -5.1 in handicapDifferential. The field datatype is FLOAT.
Using AVG() on the same result with this query
SELECT AVG(`handicapDifferential`) as `avg`
FROM `rounds`
WHERE `user` = 18956 AND `handicapDifferential` IS NOT NULL
ORDER BY `handicapDifferential` DESC, `date` DESC
LIMIT 0, 2
Gives -9.485714214188713 where I expect -3.25.
Here is a fiddle demonstrating the result and the issue: http://sqlfiddle.com/#!9/32acd/3
What am I doing incorrectly here?

Alter your query to
SELECT
AVG(items.avg)
FROM
(SELECT
`handicapDifferential` AS `avg`
FROM
`rounds`
WHERE `user` = 18956
AND `handicapDifferential` IS NOT NULL
ORDER BY `handicapDifferential` DESC,
`date` DESC
LIMIT 0, 2) items
refer link
Explanation : AVG is a an aggregate keyword in MySQL and you should have given a result set as the input as per your requirement. But u called AVG as a member in your query.

Related

how to implement two aggregate functions on the same column mysql

SELECT max(sum(`orderquantity`)), `medicinename`
FROM `orerdetails`
WHERE `OID`=
(
SELECT `OrderID`
FROM `order`
where `VID` = 5 AND `OrerResponse` = 1
)
GROUP BY `medicinename`
i want to get the max of the result(sum of the order quantity) but it gives error any soultion to solve this
You don't need Max() here. Instead sort your recordset by that Sum('orderquantity') descending, and take the first record returned:
SELECT sum(`orderquantity`) as sumoforderqty, `medicinename`
FROM `orerdetails`
WHERE `OID`=
(
SELECT `OrderID`
FROM `order`
where `VID` = 5 AND `OrerResponse` = 1
)
GROUP BY `medicinename`
ORDER BY sumoforderqty DESC
LIMIT 1

Reorder results from another query

SELECT * FROM (
SELECT * FROM cars WHERE site = '5'
ORDER BY cost DESC LIMIT 0 , 10
)
ORDER BY time
How would I execute a sql query like this? So first it selects the 10 cars with the highest cost, THEN it reorders those 10 cars by what time they were added to the DB.
I tried to figure it out but I just cannot get a grip on the syntax :P
Just give an alias to the sub-query.
SELECT * FROM (
SELECT * FROM `cars` WHERE `site` = '5'
ORDER BY `cost` DESC LIMIT 0 , 10
)t
ORDER BY `time`;
This query will give you the desired results
SELECT * FROM ( SELECT * FROM cars WHERE site = 5
ORDER BY cost DESC LIMIT 0 , 10 ) as t ORDER BY time

How do i join 2 queries?

select a.nume_echipament,
a.producator,
a.seria,
b.uc,
b.port ,
a.durata_aprovizionare as durata_aprovizionare,
( SELECT sec_to_time(count(starea)*5) from echipamente inner join
aprovizionari on
echipamente.nume_echipament=aprovizionari.nume_echipament
where
(
echipamente.ora>aprovizionari.ora_aprov
and
echipamente.data>aprovizionari.data_aprov)
and starea='1'
and
echipamente.nume_echipament='automat_imbuteliere') as durata_functionare,
a.durata_viata as durata_viata,
( select data_aprov from aprovizionari where nume_echipament='automat_imbuteliere' order by date(data_aprov) desc, time(ora_aprov) desc limit 1) as data_aprov,
( select ora_aprov from aprovizionari where nume_echipament='automat_imbuteliere' order by date(data_aprov) desc, time(ora_aprov) desc limit 1) as ora_aprov,
(select sec_to_time(count(starea)*5)) as durata_totala
from date_tehnice a
inner join echipamente b on a.nume_echipament=b.nume_echipament
inner join aprovizionari c on c.nume_echipament=a.nume_echipament
where a.nume_echipament='automat_imbuteliere'
and
b.starea='1';
The above query work perfectly fine, but i also need to get the result from this query
select `starea` from echipamente where nume_echipament='automat_imbuteliere' order by data desc, ora desc limit 1 ;
As you can see in the first query it depends only on b.starea='1', whereas the second query needs to get the latest value of 'starea'. 'starea' has only 0 and 1 values. So, how do i combine this 2 queries into 1 query in order to get the last value value of 'starea'?
To get the second query to have its own row then UNION them like this with as many null columns as needed to match the number of columns in your first query.
UNION
select
(select `starea` from echipamente where nume_echipament='automat_imbuteliere' order by data desc, ora desc limit 1 )
, null
, null
, null
, null
, null

Unknown Column in 'IN/ALL/ANY' subquery

I've got 2 tables: members and member_logs.
Members can belong to groups, which are in the members table. Given a date range and a group I'm trying to figure out how to get the 10 days with the highest number of successful logins. What I have so far is a massive nest of subquery terror.
SELECT count(member_id) AS `num_users`,
DATE_FORMAT(`login_date`,'%Y-%m-%d') AS `reg_date`
FROM member_logs
WHERE `login_success` = 1
and `reg_date` IN
(SELECT DISTINCT DATE_FORMAT(`login_date`,'%Y-%m-%d') AS `reg_date`
FROM member_logs
WHERE `login_success` = 1
and (DATE_FORMAT(`login_date`,'%Y-%m-%d') BETWEEN '2012-02-25' and '2014-03-04'))
and `member_id` IN
(SELECT `member_id`
FROM members
WHERE `group_id` = 'XXXXXXX'
and `deleted` = 0)
ORDER BY `num_users` desc
LIMIT 0, 10
As far as I understand what is happening is that the WHERE clause is evaluating before the subqueries generate, and that I also should be using joins. If anyone can help me out or point me in the right direction that would be incredible.
EDIT: Limit was wrong, fixed it
The first subquery is totally unnecessary because you can filter by dates directly in the current table member_logs. I also prefer a JOIN for the second subquery. Then what you are missing is grouping by date (day).
A query like the following one (not tested) will do the job you want:
SELECT COUNT(ml.member_id) AS `num_users`,
DATE_FORMAT(`login_date`,'%Y-%m-%d') AS `reg_date`
FROM member_logs ml
INNER JOIN members m ON ml.member_id = m.member_id
WHERE `login_success` = 1
AND DATE_FORMAT(`login_date`,'%Y-%m-%d') BETWEEN '2012-02-25' AND '2014-03-04'
AND `group_id` = 'XXXXXXX'
AND `deleted` = 0
GROUP BY `reg_date`
ORDER BY `num_users` desc
LIMIT 10
SELECT count(member_id) AS `num_users`,
DATE_FORMAT(`login_date`,'%Y-%m-%d') AS `reg_date`
FROM member_logs
WHERE `login_success` = 1
and `login_date` IN
(SELECT `login_date`
FROM member_logs
WHERE `login_success` = 1
and (DATE_FORMAT(`login_date`,'%Y-%m-%d') BETWEEN '2012-02-25' and '2014-03-04'))
and `member_id` IN
(SELECT `member_id`
FROM members
WHERE `group_id` = 'XXXXXXX'
and `deleted` = 0)
Group by `login_date`
ORDER BY `num_users` desc
LIMIT 0, 10
As a slightly more index friendly version of the previous answers;
To make the query index friendly, you shouldn't do per row calculations in the search conditions. This query removes the per row calculation of the string format date in the WHERE, so it should be faster if there are many rows to eliminate by date range;
SELECT COUNT(*) num_users, DATE(login_date) reg_date
FROM member_logs JOIN members ON member_logs.member_id = members.member_id
WHERE login_success = 1 AND group_id = 'XXX' AND deleted = 0
AND login_date >= '2012-02-25'
AND login_date < DATE_ADD('2014-03-04', INTERVAL 1 DAY)
GROUP BY DATE(login_date)
ORDER BY num_users DESC
LIMIT 10

re-sorting the output of a SELECT LIMIT query

Fellow coders, i have a table that contains a number of rows each with a date column. I would like to select the last 6 most recent rows. I can do that like this:
SELECT *
FROM `Stats`
WHERE `ProjectID` = ?
ORDER BY `StatsDate` DESC
LIMIT 6
This returns the rows I need but they are returned in DESC date order. What I want is the last 6 rows in ASC date order. How can I re-sort the output of the SELECT? Any ideas?
thanks
SELECT *
FROM (
SELECT *
FROM `Stats`
WHERE `ProjectID` = ?
ORDER BY `StatsDate` DESC
LIMIT 6
) s
ORDER BY s.StatsDate
Surround the query in an outer query and order that in a different order.
SELECT * FROM
(
SELECT *
FROM `Stats`
WHERE `ProjectID` = ?
ORDER BY `StatsDate` DESC
LIMIT 6
) s
ORDER BY `StatsDate` ASC
SELECT *
FROM (
FROM `Stats`
WHERE `ProjectID` = ?
ORDER BY `StatsDate` DESC
LIMIT 6
) as t
ORDER BY t.`StatsDate` ASC;