Why does my SQL statement show unknown column in WHERE clause - mysql

I do not understand why I get an error saying "Unknown column 'cyclist.ISO_id' in 'where clause'"
SELECT name, gender, height, weight FROM Cyclist LEFT JOIN Country ON Cyclist.ISO_id = Country.ISO_id WHERE cyclist.ISO_id = 'gbr%';

It looks like your table name is Cyclist, not cyclist - capital C. In your WHERE clause your're therefore referencing the column of a table which does not exist.

This is mostly relevant with OS. Naming Conventions are case sensitive in Unix whereas not in windows OS. You can change the parameter value of lower_case_table_names system variable to 0/2 depending on OS. The detail explanation is available at http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html

From the docs (with my emphasis):
Although database, table, and trigger names are not case sensitive on
some platforms, you should not refer to one of these using different
cases within the same statement. The following statement would not
work because it refers to a table both as my_table and as MY_TABLE:
mysql> SELECT * FROM my_table WHERE MY_TABLE.col=1;
Column, index, stored routine, and event names are not case sensitive
on any platform, nor are column aliases.
So use either cyclist or Cyclist but consistently.

Related

What MySQL commands can use column order instead of names

I have and old MySQL database where I need to insert new columns into tables (to support new parts of the front-end). But some of the old parts use SQL commands that depend on column count and order instead of their names. e.g.:
INSERT INTO `data` VALUES (null /*auto-id*/, "name", "description", ...)
When I add new columns into this table, I get the error:
1136 - Column count doesn't match value count at row 1
Right now I know about the INSERT which needs to be changed to:
INSERT INTO `data` (`name`, `desc`, ...) VALUES ("name", "description", ...)
The question is: are there any other commands that can use similar syntax that rely on an order or count of the columns instead of their names? I need to update all the old SQL commands before updating the DB and using trial & error method would be really long.
SELECTs are not a problem, because the front-end uses associative mapping and correctly uses their names everywhere so new columns will be just ignored. Also I'm sure there are no commands that modifying the DB structure (e.g. ALTER TABLE).
You ruled out data structure modifying queries, so this leaves us with insert, update, delete, and select.
Insert you are already aware of.
Update requires each updated field to be specified, so mostly that's ok. However, subqueries may be used in the where clause, and mysql allows multi-table updates, so my points around select do apply.
Delete applies to a whole record, so there is nothing that an extra field would influence. However, subqueries may be used in the where clause, so my points around select do apply.
You tried to rule out select, but you should not. It is not only the final resultset that can be influenced by a new field:
A subquery may use select * that and an extra field may cause error in the outer query. For example the newly introduced field mayhave the same name as another field in the outer query leading to ambiguous field name error.
If select * is used in union, then column counts may not match after adding a new field.
Natural joins may also be affected by an introduction of a new field.

Column values are not overriden in result set

Is it a standard behavior for HeidiSQL not to override fields that should be overriden in the result set?
I run SQL query, where two tables have the same fields, one table is main and other is from join. I have to select all fields from main table (e.g. use "*"), and some fields from joined table must override values of main table. And it actually works when we fetch results with PDO (cause as a result we got an array value with the same key overrides previous one). but in HeidiSQL I got this:
Ok, got it by myself.
According to documentation:
MySQL permits duplicate column names. That is, there can be more than one select_expr with the same name. This is an extension to standard SQL. Because MySQL also permits GROUP BY and HAVING to refer to select_expr values, this can result in an ambiguity:
SELECT 12 AS a, a FROM t GROUP BY a;
In that statement, both columns have the name a. To ensure that the correct column is used for grouping, use different names for each select_expr.
I haven't attached importance to this before.

Problems with division using a constant in another table

I am displaying recorded values of pressure.
I always store pressure as PSI in my database, knowing that I can convert it to BAR by dividing by 14.5
So, I have a table called configuration and one called measurements and I want so say
SELECT pressure DIV my_db.configuration.conversion_factor AS pressure FROM my_db.measurements WHERE ... and my front-end s/w will set my_db.configuration.conversion_factor to either 1 or 14.5 as appropriate.
But I am getting an error unknown column 'my_db.configuration.conversion_factor' in 'filed list'.
Since I am cut/pasting, I doubt that it is a spelling error - so what is wrong with my query?
[Update]
#JimGarrison set me on the correct path. What I needed was
SELECT pressure DIV (SELECT conversion_factor FROM my_db.configuration WHERE 1) AS pressure FROM my_db.measurements WHERE ...
Note: I add that WHERE 1 for anyone reading this question in future; I only have a single row in the configuration table, so I don't need a WHERE - but you might ..
Thanks, Jim
You can't refer to a field in a second table like that. my_db.configuration is a table with rows and columns. How does SQL know which row you want to use?
What I think you're looking for is
select pressure div (select conversion_factor from my_db.configuration where <???>=<???>) ...
where <???> is where you'd put the key column name and value for the entry you want to use from the conversion_factor table.
You have to list all the tables you want to reference in a FROM clause — in this case, the FROM clause.
SELECT pressure DIV my_db.configuration.conversion_factor AS pressure
FROM my_db.measurements
CROSS JOIN my_db.configuration
WHERE ...
The CROSS JOIN is used assuming there's just one row in your configuration table. It doesn't require a join condition.
Or you can use a sub-select as Jim Garrison suggests in his answer. It's probably cleaner. But note that he referenced the configuration table in a FROM clause.

Confused with selecting data from db in mysql [duplicate]

This question already has an answer here:
Syntax error due to using a reserved word as a table or column name in MySQL
(1 answer)
Closed 8 years ago.
I have 2 tables: PLAYER and GROUP.
When I call:
SELECT * FROM PLAYER
Everything is OK but when I call:
SELECT * FROM GROUP
There is error:
#1064 - You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'GROUP' at line 1`
I don't understand why there is such error.
GROUP is a reserved word and it must be escaped with back ticks.
SELECT * FROM `GROUP`
It's also better practice to avoid using table names or columns that are reserved words. Also, specify a column list and not use *.
GROUP is a reserved keyword . You have to escape it, like so
SELECT * FROM `GROUP`
Things to note:
It is highly recommended not to name the table group, it is better to use the plural Groups.
Also, try to avoid *.
Just as you use the reserved keywords SELECT and FROM for constructing your query, there are other reserved keywords like the ones in the following list that you may want to avoid when naming all your tables, views, constraints and columns.
List of (some) reserved keywords: WHERE, ORDER, GROUP, UPDATE, DELETE, CHECK, CHANGE, LIKE etc...
Therefore, in your case the DB Engine is complaining because a query
needs 1 mandatory clause SELECT and optional clauses FROM, WHERE,
ORDER BY, GROUP BY, HAVING, LIMIT etc... read more here
We might be tempted to use these keywords; especially if they've been modeled in our problem domain (or in the diagrams). For example, a client placing an order yields 2 Entities CLIENT and ORDER etc. or a mechanic performing a check giving MECHANIC and CHECK. or even a FACEBOOK_USER expressing a LIKE. or in your case there might be a GROUP of PEOPLE for example.
As a general rule, you can transform your entities like so to avoid problems:-
a) The Entity is always modeled (on paper) as singular as it represents a concept/asset/person in the real world or problem domain. eg. ORDER, LIKE, CHECK, STUDENT, CAR
b) the corresponding DB Table it is transformed into is always named using plural. The logic is that the table will contain lots of instances of that Entity. Therefore ORDERS, LIKES, CHECKS, STUDENTS, CARS
In the end, you decide because you really can use GROUP if you really
want or need to make your table name like a reserved word. Just
remember to give them a special treatment by putting them in quotes
using the backtick (“`”) when querying. At the moment of creation the DB engine
won't complain, trusting that you know what you're doing.

Selecting a column that is also a keyword in MySQL

For some reason, the developers at a new company I'm working for decided to name their columns "ignore" and "exists". Now when I run MySQL queries with those words in the where clause, I get a syntax error; however, I can't seem to figure out how to reference those columns without running into an error. I tried setting them as strings, but that doesn't make any sense.
Help?
Also, is there a term for this kind of mismatch?
put the names in backticks:
`ignore`, `exists`
If you're working across multiple tables or databases you need to escape the database name, table name, and field name separately (if each matches a keyword):
SELECT * FROM `db1`.`table1`
LEFT JOIN `db2`.`table2` on `db1`.`table1`.`field1`=`db2`.`table2`.`field2`
Only the portions that actually match a keyword have to be escaped, so things like:
select * from `db1`.table
are ok too.
The official term is "idiocy" :-) You can put backticks around the names such as
`ignore`
but I would give serious consideration to changing the names if possible. Backticks are not standard SQL, and I prefer my column names to be a little more expressive. For example, ignoreThisUser or orderExists (the general rule I try to follow is to have a noun and a verb in there somewhere).
Interestingly, some DBMS' can figure out not to treat it as a reserved word based on context. For example, DB2/z allows the rather hideous:
> CREATE TABLE SELECT ( SELECT VARCHAR(10) );
> INSERT INTO SELECT VALUES ('HELLO');
> SELECT SELECT FROM SELECT;
SELECT
---------+---------+---------+--------
HELLO
DSNE610I NUMBER OF ROWS DISPLAYED IS 1