Using alias in sql to compute other value - mysql

I've this query. I want to perform addition on Total1 and Total2 which are aliases. My query is not working mysql is showing Unknown column error.
SELECT p.Quantity*p.Price AS Total1,
p.Quantity+p.Tax AS Total2,
p.Total1+p.Total2 AS Total
FROM p
ORDER BY id

You can't reuse aliases in your select clause
SELECT p.Quantity*p.Price AS Total1,
p.Quantity+p.Tax AS Total2,
p.Quantity*p.Price + p.Quantity+p.Tax AS Total
FROM p
ORDER BY id
Only in group, having, order clauses.

Aliases are evaluated at the very end during the lifecylce of a select statement. These are normally for output purposes only and are not usable for computation
The Sequence of a select statement Evaluation is:
1. From
2. Where
3. Order / grouping
4. Select ( fields and allias)

Related

Average after group by in SQL query

select avg(select count(aid)
from athlete
group by codepays)
I get a "more than one row error".
How with I go about getting the average of the result from my fist select ?
You need to use a table expression (subquery).
For example:
select avg(cnt)
from (
select count(aid) as cnt
from athlete
group by codepays
) x
You can do this using division:
select count(aid) / count(distinct codepay)
from athlete;
No subqueries are necessary.
(Although the arithmetic needs to be tweaked if codepay can actually be NULL.)

The alias of the scalar sub query is not recognized in the select statement

For Example,
SELECT
cost,
(SELECT MIN(cost) FROM stock) AS min_cost,
price - min_cost
FROM stock
When I execute this sql statement, I get the following error. What is the reason?
ERROR 1054 (42S22) at line 1: Unknown column 'min_cost' in 'field list'
You can not directly use an aliased column within a main query, that needs to be generated within a subquery.
This usage is also possible as an alternative :
SELECT cost,
price - (SELECT MIN(cost) FROM stock) AS cost_diff
FROM stock
The columns produced by expressions in a query are not immediately available to the WHERE clause, though they may be available to the GROUP BY, HAVING, or ORDER BY clauses.
If you need to use a named expression in the WHERE clause you'll need to include your query as a "table expression" of another query.
For example:
select
*,
price - min_cost
from (
SELECT
cost,
(SELECT MIN(cost) FROM stock) AS min_cost
FROM stock
) x
You can use this strategy to produce named columns for complex expressions that need to be combined further into other complex formulas/expressions.
You need to write the expression, alias will be not recognized
SELECT
cost,
(SELECT MIN(cost) FROM stock) AS min_cost,
price - (SELECT MIN(cost) FROM stock)
FROM stock

In MySQL, what does this simple nested SELECT clause mean exactly?

Here is the example from this thread:
select (
select distinct Salary from Employee order by Salary Desc limit 1 offset 1
)as second;
The select(...) as second looks confusing to me because I've never seen a query-set instead of column names can be used as the argument of SELECT..
Does anyone have ideas about how to understand nested select clause like this? Is there any tutorials about this feature?
That's a subquery in the SELECT list of a query.
To get there, let's look at some other examples
SELECT t.id
, 'bar' AS foo
FROM mytable
WHERE ...
LIMIT ...
'bar' is just a string literal that gets returned in every row (in a column named foo) in the resultset from the query.
Also, MySQL allows us to run a query without a FROM clause
SELECT 'fee' AS fum
We can also put a subquery in the SELECT list of a query. For example:
SELECT t.id
, (SELECT r.id FROM resorts r ORDER BY r.id ASC LIMIT 1) AS id
FROM mytable
WHERE ...
LIMIT ...
The query pattern you asked about is a SELECT statement without a FROM clause
And the only expression being returned is the result from a subquery.
For example:
SELECT e.salary
FROM Employee e
GROUP BY e.salary
ORDER BY e.salary DESC
LIMIT 4,1
If this query runs, it will return one column, and will return either one or zero rows. (No more than one.) This satisfies the requirements for a subquery used in a SELECT list of another query.
SELECT ( subquery ) AS alias
With that, the outer query executes. There's no FROM clause, so MySQL returns one row. The resultset is going to consist of one column, with a name of "alias".
For each row returned by the outer query, MySQL will execute the subquery in the SELECT list. If the subquery returns a row, the value of the expression in the SELECT list of the subquery is assigned to the "alias" column of the resultset. If the execution of the subquery doesn't return a row, then MySQL assigns a NULL to the "alias" column.

Nested SQL Query

I have problems with the following SQL Query:
SELECT job
FROM (SELECT job, COUNT(*) AS cnt
FROM Employee
GROUP BY job)
WHERE cnt=1
As Result it should only shows all jobs where cnt (count of jobs) equals 1.
When I test the select query above on Fiddle, I get following error :
Incorrect syntax near the keyword 'WHERE'.
SQLFiddle: http://sqlfiddle.com/#!6/d812a/7
No need to increase complexity by using sub-query when it is not require
SELECT job, count(job)
FROM Employee
GROUP BY job
having count(job)=1;
You need to provide alias name to the nested query
SELECT A.job
FROM (SELECT job, COUNT(*) AS cnt
FROM Employee
GROUP BY job)A
WHERE A.cnt=1
You forget to add the alias name.
Please change the query like this
SELECT job
FROM (SELECT job, COUNT(*) AS cnt
FROM Employee
GROUP BY job) As MyTable
WHERE cnt=1
You should have to give the alias name for the inner query when you are using the select and where clauses outside.
You should use the HAVING syntax :
SELECT job, COUNT(*) AS cnt
FROM Employee
GROUP BY job
HAVING cnt = 1;
You should use the HAVING clause which is done for that kind of thing. Your request will be simply :
SELECT job FROM Employee GROUP BY job
HAVING COUNT(id)=1
The documentation states that
The SQL standard requires that HAVING must reference only columns in
the GROUP BY clause or columns used in aggregate functions. However,
MySQL supports an extension to this behavior, and permits HAVING to
refer to columns in the SELECT list and columns in outer subqueries as
well.
The important thing to note is that contrary to the WHERE clause, you can use aggregate funcitons (like count, max, min ...) in the HAVING clause.

Mysql database query not working as expected

Why can't I write queries like
select *
from STAFF
having Salary > avg(salary);
in SQL?
PS: to find staff members with a salary = avg salary, I need to write
select *
from STAFF
having Salary > (select avg(Salary) from STAFF);
Is there any other way to do this?
An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference.
The functions SUM(),AVG(),MIN(),MAX(),COUNT(),etc are called aggregate functions. Read more here.
Example using WHERE clause :
select *
from staff
where salary > (select avg(salary) from staff)
See example in SQL Fiddle.
Example using HAVING clause :
select deptid,COUNT(*) as TotalCount
from staff
group by deptid
having count(*) >= 2
See example in SQL Fiddle.
Where can we use having clause:
Having clause specifies a search condition for a group or an aggregate. HAVING can be used only with the SELECT statement. HAVING is typically used in a GROUP BY clause. When GROUP BY is not used, HAVING behaves like a WHERE clause.
Read more here.