Why must every derived table have its own alias? - mysql

select a as average,name
from (select avg(marks) as a,name
from marks,student where rollno=roll group by marks.roll);
ERROR 1248 (42000): Every derived table must have its own alias
I know the correction. Just want to know why I have to use the alias?
select a as average,name
from (select avg(marks) as a,name
from marks,student where rollno=roll group by marks.roll)xxx;

It's just a quirk in the design of MySQL. Oracle and SQL-Server don't require the alias in this case.

If you want to select, you need to declare a From-clause. If there is not one, like in subselects, you are not able to even select. thats why SQL syntax defines to make a alias for each subselected table.

Related

Error code :1054 Unknown column, while using joins in mysql

Hi I am writing a query where i want 2 columns from 2 different sql tables, the 2 tables are "success_ logs" and "defect_logs",The query-
SELECT DISTINCT success_logs.sl_frn_rfid_id, defect_logs.sl_frn_rfid_id
FROM success_logs
INNER JOIN defect_logs dl ON dl.frn_company_id = success_logs.frn_company_id WHERE frn_company_id="abc123";
but i am getting an error in the first line
Error Code: 1054. Unknown column 'defect_logs.sl_frn_rfid_id' in 'field list'
I am not getting where i am going wrong , most of the questions regarding the error was resolved using an alias or their issue was in the "Where" clause. Not getting where the issue is here.
If you are using an alias, I think you need to change the first line from
SELECT DISTINCT success_logs.sl_frn_rfid_id, defect_logs.sl_frn_rfid_id
to
SELECT DISTINCT success_logs.sl_frn_rfid_id, dl.sl_frn_rfid_id
Once you give the tables aliases in the FROM clause, you need to use them throughout the query. That is, defect_logs is not recognized.
I would recommend using aliases for all the tables, so:
SELECT DISTINCT sl.sl_frn_rfid_id, dl.sl_frn_rfid_id
FROM success_logs sl INNER JOIN
defect_logs dl
ON dl.frn_company_id = sl.frn_company_id
WHERE dl.frn_company_id = 'abc123';
Notes:
Only use SELECT DISTINCT if you intend to incur the overhead for removing duplicates. Usually, it is not necessary.
The standard SQL delimiter for strings is the single quote, so I recommend that you use that.
You need to qualify frn_company_id. It is in both tables, so it is not clear which column the WHERE is referring to.

Every derived table must have its own alias - when is something a derived table?

First, let me note that I am aware of the other threads with a similar question, but they didn't help my understanding very much. On the opposite, I now sometimes run into the problem that assigning aliases ruins my code, as described below.
So I got said error message very often, and in turn started to give aliases to those subqueries which I thought were 'derived tables', but sometimes when doing so, I now get the message 'You have an error in your SQL syntax' instead, and after removing the 'AS ...' statement, everything runs fine.
So I am really trying to figure out when exactly something is a derived table and hence needs and alias, and when not.
I will give you an example: Given some tables P, LTP, and T, the following query runs flawless:
SELECT DISTINCT pname FROM P WHERE P.pnr IN (SELECT pnr FROM LTP WHERE lnr='L1' AND tnr IN (SELECT tnr FROM T WHERE gewicht>10));
How are the statements in the brackets not derived tables though? I would have assumed that in this case I would have had to give them aliases like this:
SELECT DISTINCT pname FROM P WHERE P.pnr IN (SELECT pnr FROM LTP WHERE lnr='L1' AND tnr IN (SELECT tnr FROM T WHERE gewicht>10) AS TNEW) AS LTPNEW;
but both of these ruin the code.
I would really appreciate if somebody could point out to me what exactly I am misunderstanding.
If the subquery is in the table_references portion of a query (the FROM clause and all accompanying JOINs), it needs to include an alias.
If the subquery appears elsewhere, like in the WHERE or SELECT section, it's just a regular subquery and no aliasing is required.
From the documentation:
Derived tables is the internal name for subqueries in the FROM clause.
As a rule of thumb, if you can reference a column from the subquery by name, then the subquery needs an alias to prevent ambiguity.

What does the 'a' do in this MySQL query? It doesn't run without it

The 'a' at the end of this:
SELECT
email_home
FROM
(SELECT email_home FROM sales
UNION ALL
SELECT email_work FROM sales) a
What's it do/for? The code doesn't run without it. Thanks.
It's just an alias. Mysql requires all sub queries like that require a specific name. People just use 'a' as convention if they aren't really going to use it.
You could specify the column name thusly:
a.email_home
It sets the name of an alias to the table to "a".
Presumably, you could reference objects in that table by using "a.[columnName]" for future stuff.
As you are using subquery in From clause MySql requires alias name. In your case "a" is just a alias given to your subquery in From clause. for detail information read this

Why does MySQL allow you to group by columns that are not selected

I'm reading a book on SQL (Sams Teach Yourself SQL in 10 Minutes) and its quite good despite its title. However the chapter on group by confuses me
"Grouping data is a simple process. The selected columns (the column list following
the SELECT keyword in a query) are the columns that can be referenced in the GROUP
BY clause. If a column is not found in the SELECT statement, it cannot be used in the
GROUP BY clause. This is logical if you think about it—how can you group data on a
report if the data is not displayed? "
How come when I ran this statement in MySQL it works?
select EMP_ID, SALARY
from EMPLOYEE_PAY_TBL
group by BONUS;
You're right, MySQL does allow you to create queries that are ambiguous and have arbitrary results. MySQL trusts you to know what you're doing, so it's your responsibility to avoid queries like that.
You can make MySQL enforce GROUP BY in a more standard way:
mysql> SET SQL_MODE=ONLY_FULL_GROUP_BY;
mysql> select EMP_ID, SALARY
from EMPLOYEE_PAY_TBL
group by BONUS;
ERROR 1055 (42000): 'test.EMPLOYEE_PAY_TBL.EMP_ID' isn't in GROUP BY
Because the book is wrong.
The columns in the group by have only one relationship to the columns in the select according to the ANSI standard. If a column is in the select, with no aggregation function, then it (or the expression it is in) needs to be in the group by statement. MySQL actually relaxes this condition.
This is even useful. For instance, if you want to select rows with the highest id for each group from a table, one way to write the query is:
select t.*
from table t
where t.id in (select max(id)
from table t
group by thegroup
);
(Note: There are other ways to write such a query, this is just an example.)
EDIT:
The query that you are suggesting:
select EMP_ID, SALARY
from EMPLOYEE_PAY_TBL
group by BONUS;
would work in MySQL but probably not in any other database (unless BONUS happens to be a poorly named primary key on the table, but that is another matter). It will produce one row for each value of BONUS. For each row, it will get an arbitrary EMP_ID and SALARY from rows in that group. The documentation actually says "indeterminate", but I think arbitrary is easier to understand.
What you should really know about this type of query is simply not to use it. All the "bare" columns in the SELECT (that is, with no aggregation functions) should be in the GROUP BY. This is required in most databases. Note that this is the inverse of what the book says. There is no problem doing:
select EMP_ID
from EMPLOYEE_PAY_TBL
group by EMP_ID, BONUS;
Except that you might get multiple rows back for the same EMP_ID with no way to distinguish among them.

Creating a column name alias from a select statement

I am trying to create a column alias by looking up a value in another table. This is the MySQL I am trying but keep getting syntax errors - any help would be appreciated.
SELECT
product_code,
bField1 as (select [label_value] from [labels] where [field_value]='bField1'),
bField2 as (select [label_value] from [labels] where [field_value]='bField2'),
....
FROM products
try as folow:
SELECT
product_code,
(select [label_value] from [labels] where [field_value]='bField1') as bField1,
(select [label_value] from [labels] where [field_value]='bField2') as bField2,
....
FROM products
What you wish is not possible wtih only MySQL.
See below for similar questions:
Dynamic column alias based on column value
Specifying column alias with user-defined variable
I'm not sure why exactly you want to do this but it's always possible to incorporate the alias selection logic with the server side language that is dynamically creating the query. But of course, this would then be a two step process but you are not actually losing out as in your example you are using sub queries anyways.