MySQL query sum result divide by number of row (Average) - mysql

I have following data in MySQL and i want to sum (total) and then divide by number for row.
Example:
I want to sum all number in AcctSessionTime column and divide that with number of items so in our case 6+4+3+31=44 divide them with 4 number of row.
How do i craft query to do all in single query?
mysql> select AcctStartTime,AcctStopTime,AcctSessionTime
from radacct
where UserName='spatel' AND SipResponseCode='200';
+---------------------+---------------------+-----------------+
| AcctStartTime | AcctStopTime | AcctSessionTime |
+---------------------+---------------------+-----------------+
| 2015-06-04 15:32:03 | 2015-06-04 15:32:09 | 6 |
| 2015-06-04 16:11:27 | 2015-06-04 16:11:31 | 4 |
| 2015-06-04 16:13:37 | 2015-06-04 16:13:40 | 3 |
| 2015-06-05 11:44:31 | 2015-06-05 11:45:02 | 31 |
+---------------------+---------------------+-----------------+
4 rows in set (0.00 sec)
Notes: above is example data we have actual data in thousands of rows.

The calculation SUM(RowData) / #Rows is an Average of RowData - this is already supported natively as the AVG aggregate function:
select AVG(AcctSessionTime)
from radacct
where UserName='spatel' AND SipResponseCode='200';
You can also do grouped averages with a GROUP BY statement, if required

mysql> select sum(AcctSessionTime) div count(AcctSessionTime) as result from radacct where UserName='spatel' AND SipResponseCode='200';
| result |
+--------+
| 11 |
You can try this.

You can try this:
Select AVG(AcctSessionTime) from radacct where UserName='spatel' AND SipResponseCode='200';

Related

How to reuse variables in the select statement of mysql

I would like to use mysql variables to prevent same statements. In the following example i would like to sum the salary of an each employee and also sum it twice times. Of course the second column is wrong.
MariaDB [Messdaten]> select * from t;
+----+----------+--------+
| id | employee | salery |
+----+----------+--------+
| 1 | 10 | 1000 |
| 2 | 10 | 2000 |
| 3 | 20 | 3000 |
| 4 | 20 | 4000 |
+----+----------+--------+
4 rows in set (0.000 sec)
MariaDB [Messdaten]> select employee, #x:=sum(salery), 2*#x from t group by employee;
+----------+-----------------+-------+
| employee | #x:=sum(salery) | 2*#x |
+----------+-----------------+-------+
| 10 | 3000 | 14000 |
| 20 | 7000 | 14000 |
+----------+-----------------+-------+
2 rows in set (0.001 sec)
Of course i could use select employee, sum(salery), 2*sum(salery) but in my real use case the statements are very big and therefore bad readable.
What ist going wrong and if this is a gap of mysql are there some workarounds?
You can use a subquery like so to get the correct result while only summing (or executing a more complex statement) once
SELECT
employee,
totalSalary,
totalSalary*2 AS doubleSalary
FROM (
SELECT
employee,
sum(salary) AS totalSalary
FROM employees
GROUP BY employee
) AS employeeSalaries;
The unexpected variable behaviour is described in the MySQL docs here.
HAVING, GROUP BY, and ORDER BY, when referring to a variable that is assigned a value in the select expression list do not work as expected because the expression is evaluated on the client and thus can use stale column values from a previous row.

Properly SQL query

I need to skip results with high price per day. I've got a table like this:
+------+-------------+-------+
| days | return_date | value |
+------+-------------+-------+
| 2 | 2017-12-27 | 15180 |
| 3 | 2017-12-28 | 14449 |
| 4 | 2017-12-29 | 13081 |
| 5 | 2017-12-30 | 11203 |
| 6 | 2017-12-31 | 9497 |
| 6 | 2017-12-31 | 9442 |
+------+-------------+-------+
How can I print only the lowest price for 6 days (9442 in this example).
We can use a GROUP BY clause and an aggregate function. For example:
SELECT t.days
, t.return_date
, MIN(t.value) AS min_value
FROM mytable t
GROUP
BY t.days
, t.return_date
This doesn't really "skip" rows. It accesses all the rows that satisfy the conditions in the WHERE clause (in this example, every row in the table). Then MySQL collapses rows into groups (in this example, rows with identical values of days and return_date get put into a group. The MIN(t.value) aggregate function selects out the minimum (lowest) value out of the group.
The query above is just an example of one approach of satisfying a particular specification.

Sql query- Get results between two different date columns with its exact days match

I have the following 2 columns in 'deals' table.
- subscribed_date
- expired_date
I want the SQL query that to filter the records with 2 columns difference as follows
(expired_date - subscribed_date) == 7 days
For eg:
id | subscribed_date | expired_date
1 | 2015-07-04 04:13:29 | 2015-09-03 04:13:29
2 | 2015-06-03 04:13:29 | 2015-06-10 04:13:29
3 | 2015-01-05 04:13:29 | 2015-02-08 04:13:29
In the above example, the result should be id=2 because its difference is 7 days.
Is it possible through SQL query without iterations?
Thanks in advance for your help!
The easiest way would be to use timestampdiff function
mysql> select timestampdiff(day,'2015-06-03 04:13:29','2015-06-10 04:13:29') as d ;
+------+
| d |
+------+
| 7 |
+------+
So the query becomes
select * from deals
where timestampdiff(day,subscribed_date,expired_date) = 7
Why not just SELECT * FROM deals WHERE DATEDIFF(expired_date, subscribed_date) = 7?
Further info here.

MySQL HAVING Clause return empty set?

I am having a table below, and I need to write code that extract the rows with budget greater than the average budget.
+------+-----------------+--------+
| Code | Name | Budget |
+------+-----------------+--------+
| 14 | IT | 65000 |
| 37 | Accounting | 15000 |
| 59 | Human Resources | 240000 |
| 77 | Research | 55000 |
+------+-----------------+--------+
I know this works:
SELECT * FROM Departments WHERE Budget > (SELECT AVG(Budget) FROM Departments);
but this looks ugly. This post seems to suggest having clause can simplify the query into:
SELECT * FROM Departments HAVING Budget > AVG(Budget);
but it returns empty set. Any ideas?
Thanks
This is because AVG() is aggregation function which should be used GROUP BY or with other Aggregation functions.
If not, SELECT would returns single row. for example:
mysql> SELECT * FROM test;
+------+--------+
| code | budget |
+------+--------+
| 14 | 65000 |
| 37 | 15000 |
| 59 | 240000 |
| 77 | 55000 |
+------+--------+
4 rows in set (0.00 sec)
mysql> SELECT code, budget, AVG(budget) FROM test;
+------+--------+-------------+
| code | budget | AVG(budget) |
+------+--------+-------------+
| 14 | 65000 | 93750.0000 | we got one row.
+------+--------+-------------+
1 row in set (0.00 sec)
In this case, HAVING budget > AVG(budget) means 65000 > 93750 which is false, so that returns empty list.
Your first attampt does not look like 'ugly' ;)
In mySQL, having an aggregation column with SELECT * will return the first row only.
This SQL Fiddle shows that:
SELECT *, AVG(BUDGET) FROM Departments;
will return only the first row and the average of budget of all rows.
Then, as in your first row, the budget is smaller than the average of budgets, it will return no rows.
I believe your UGLY (I don't think it is ugly) query is a good solution for this.

How return only one column as output in MySQL?

I want to return only one column as output in MySQL.
This works:
select COALESCE(sum(debit_amt),0) as credit from client_debit_bal where mob_no=id
but when I try the following query it does not:
select COALESCE(sum(debit_amt),0) as credit from client_debit_bal where mob_no=id
and cmy_code='001'
I only need credit to be outputted. What am I missing?
Are you looking for LIMIT?
LIMIT clause constrains the number of result.
You can fetch the first N rows using LIMIT [N].
Suppose there is a table like following,
tbl_t
| idx | name | age |
| 0 | Tom | 30 |
| 1 | Jerry | 25 |
| 2 | Bob | 30 |
| 3 | Ken | 45 |
Then query following statement,
SELECT name FROM tbl_t WHERE age=30
result would be {'Tom', 'Bob'}.
But if you query SELECT name FROM tbl_t WHERE age=30 LIMIT 1 then
result would be {'Tom'}.
If you want to get further information, visit http://www.mysqltutorial.org/mysql-limit.aspx .