Error code :1054 Unknown column, while using joins in mysql - 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.

Related

Issue converting Access SQL Inner Join Query to mySQL Query

I am having trouble finding the syntax issue that is causing the following query to give me no results:
SELECT Table1.Country, Table_Data2.Part, Table_Data2.Description, Sum(Table_Data2.Quantity) AS Quantity, Table1.ship_time
FROM Table1 INNER JOIN Table_Data2 ON Table1.CodeValue = Table_Data2.CodeValue
GROUP BY Table1.Country, Table_Data2.Part, Table_Data2.Description, Table1.ship_time
HAVING (((Table_Data2.Part)="BB1234" Or (Table_Data2.Part)="BB-3454") AND ((Table1.ship_time)=Date()));
Which should successfully result in a table that looks like this:
Example of what result should look like
Instead there are no syntax issues that arise nor are there any records that load.
It seems theres a syntax issue in the code above as it does not work in mySQL as it does in MS Access
Few corrections possible:
To get current date in MySQL, use Current_Date(). Date() function in MySQL has different behaviour, as it is used to extract date part out of a date(time) expression.
Parentheses around just field names are unnecessary. Use aliasing in multi table query for code clarity and read ability.
Moreover looking at your conditions in the Having clause, they are more suited to be used in the Where clause. Because they are not aggregated values and you are grouping on these same fields as well. You query will become more performant if you shift them to Where clause, as MySQL will be aggregating on filtered (reduced) data, and thus minimizing temp table space.
Also, you can rewrite multiple OR conditions on same field as IN(...)
You can rewrite as:
SELECT
t1.Country,
t2.Part,
t2.Description,
Sum(t2.Quantity) AS Quantity,
t1.ship_time
FROM Table1 AS t1
INNER JOIN Table_Data2 AS t2
ON t1.CodeValue = t2.CodeValue
WHERE
t2.Part IN ('BB1234', 'BB-3454')
AND t1.ship_time = Current_Date()
GROUP BY
t1.Country,
t2.Part,
t2.Description,
t1.ship_time

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.

Sql syntax: select without from clause as subquery in select (subselect)

While editing some queries to add alternatives for columns without values, I accidentally wrote something like this (here is the simplyfied version):
SELECT id, (SELECT name) FROM t
To my surprise, MySQL didn't throw any error, but completed the query giving my expected results (the name column values).
I tried to find any documentation about it, but with no success.
Is this SQL standard or a MySQL specialty?
Can I be sure that the result of this syntax is really the column value from the same (outer) table? The extended version would be like this:
SELECT id, (SELECT name FROM t AS t1 where t1.id=t2.id) FROM t AS t2
but the EXPLAIN reports No tables used in the Extra column for the former version, which I think is very nice.
Here's a simple fiddle on SqlFiddle (it keeps timing out for me, I hope you have better luck).
Clarification: I know about subqueries, but I always wrote subqueries (correlated or not) that implied a table to select from, hence causing an additional step in the execution plan; my question is about this syntax and the result it gives, that in MySQL seems to return the expected value without any.
What you within your first query is a correlated subquery which simply returns the name column from the table t. no actual subquery needs to run here (which is what your EXPLAIN is telling you).
In a SQL database query, a correlated subquery (also known as a
synchronized subquery) is a subquery (a query nested inside another
query) that uses values from the outer query.
https://en.wikipedia.org/wiki/Correlated_subquery
SELECT id, (SELECT name) FROM t
is the same as
SELECT id, (SELECT t.name) FROM t
Your 2nd query
SELECT id, (SELECT name FROM t AS t1 where t1.id=t2.id) FROM t AS t2
Also contains correlated subquery but this one is actually running a query on table t to find records where t1.id = t2.id.
This is the default behavior for the SQL language and it is defined on the SQL ANSI 2011 over ISO/IEC 9075-1:2011(en) documentation. Unfortunately it is not open. This behavior is described on the section 4.11 SQL-Statements.
This behavior happens because the databases process the select comand without the from clause, therefore if it encounters:
select id, (select name) from some
It will try to find that name field as a column of the outer queries to process.
Fortunately I remember that some while ago I've answered someone here and find a valid available link to an SQL ANSI document that is online in FULL but it is for the SQL ANSI 99 and the section may not be the same one as the new document. I think, did not check, that it is around the section 4.30. Take a look. And I really recommend the reading (I did that back in the day).
Database Language SQL - ISO/IEC 9075-2:1999 (E)
It's not standard. In oracle,
select 1, (select 2)
from dual
Throws error, ORA-00923: FROM keyword not found where expected
How can you be sure of your results? Get a better understanding of what the query is supposed to acheive before you write it. Even the exetended version in the question does not make any sense.

Why must every derived table have its own alias?

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.

About sql query

SELECT E.flmavailable_date,E.flmavailable_num_licenses, flmavailable_product AS SERVER
FROM (SELECT flmavailable_num_licenses,flmavailable_date
FROM licenses_available
ORDER BY flmavailable_num_licenses ASC) E
WHERE flmavailable_product <= 4;
Error:---Unknown column 'flmavailable_product' in 'field list'
Even though there is field called by that name I am getting error.
I need help to resolve this
Your outer select is trying to select a flmavailable_product from your inner select, yet there is no such field in that inner query.
Can you include the schema of the licenses_available table and a description of what your query is intended to return? This would make it easier to help you. Based on your query as it stands, it seems like you might not need that inner subquery.
You need to include the flmavailable_product field in the inner sub query if it is a column in the licences_available table, or join to the appropriate table which contains this field in the inner query :
SELECT E.flmavailable_date,E.flmavailable_num_licenses,flmavailable_product AS SERVER
FROM (SELECT flmavailable_num_licenses,flmavailable_date, flmavailable_product
FROM licenses_available ORDER BY flmavailable_num_licenses ASC)E
WHERE flmavailable_product <= 4;
Also, not sure why you are using the inner subquery as all it does is a straight select
This is the query you wanted to write.
SELECT flmavailable_num_licenses,flmavailable_date, flmavailable_product AS SERVER
FROM licenses_available
WHERE flmavailable_product <= 4
ORDER BY flmavailable_num_licenses ASC
General select query structure is:
SELECT a,b,c FROM `table`
WHERE x<=y
Here your inner query is acting as a table. However your inner query is returning only two columns: flmavailable_num_licenses & flmavailable_date.
In your outer query, you are getting an error as you are trying to select column 'flmavailable_product' which is not available in the table (Inner query).
This is clearly indicated by the error (Unknown column 'flmavailable_product' in 'field list') you are getting.
To solve this, you need to either select flmavailable_product in inner query or if it is not present there, use join to join the tables where required column is present.
Please provide table structure for exact query.