Selecting a column that is also a keyword in MySQL - 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

Related

In MySQL WHERE clause, how can I check for each item in a comma separated list against another comma separated list that may be ordered differently

I'm trying to write a query to look-up rows which contain one or more of comma-separated values. Please see scenario below:
Table: Events, target row to lookup is called "courses"
The data in the courses column is a comma separated string of course codes.
ABC123,XYZ345,ABC987
ABC123
ABC123,ABC987
XYZ345,ABC123
Now what I want to do is to do a
Select * from events where courses in ("ABC123","XYZ345");
However this returns no results.
What I want is that the where lookup to get me all rows that CONTAINS ABC123 OR XYZ345.
Could someone please help me do this?
You could use like, the % are wildcards.
select *
from events
where courses like "%ABC123%" or courses like "%XYZ345%"
There are other approaches: https://dev.mysql.com/doc/refman/8.0/en/pattern-matching.html
It might also be worth normalising the data so that each value is stored in its own row in another table rather than in a comma separated string, as using like will start to hurt performance as the table grows.
#user3783243 mentions loose matching which is a good point and just one reason why storing data like this isn't the best approach.
One way around it would be to tweak the query above to something like:
select *
from events
where courses like "%ABC123,%" or courses like "%XYZ345,%"
but this poses another problem, are the comma separated values always split by a single comma (ABC123,XYZ345) or is there any whitespace (ABC123, XYZ345).
Another problem pointed out by #GarethD is that the previous approaches won't match the last value of the comma separated string (unless it does have a trailing comma). One way I can think of is to do something like this, but it starts making the query a bit clunky, and also assumes all values are 6 characters in length, at this point, it might be worth using a regular expression.
select *
from events
where courses like "%ABC123,%" or courses like "%XYZ345,%"
or right(courses, 6) = 'ABC123' or right(courses, 6) = 'XYZ345'
If all values are indeed six characters then it might be worth trying other mysql functions such as locate, substring and regexp to try and simplify the query.
Just use FIND_IN_SET()
SELECT columns FROM events WHERE FIND_IN_SET("ABC123", courses) OR FIND_IN_SET("XYZ345", courses)
Better of course would be a normalized table, since you can't use indexes with the current design.

is there an "inverse" function to IN() in MySQL?

The scenario is this: in a table A, I have one column "tags", which is varchar(255).
In this column I store numbers, separated by commas, like this:
2,14,31,33,56
etc. there can be none, one, or several.
and I need to make a SELECT query that will return rows that have a certain number in this field. right now I'm using this method (don't be alarmed, I know its a poor way.. that's why I'm asking for help!). for example, let's assume the number I want to check is 33. the query is:
SELECT * FROM table_a WHERE
tags LIKE "%,33,%" OR tags LIKE "33,%" OR tags LIKE "%,33" OR tags LIKE "33"
I'm no expert but I know this can't be the method. The first question that comes to mind is: is there a command similar to IN() but that works the other way around?
I mean, can I tell it "find rows where 'tags' contains value 33" ?
When asking this question, I can see that there may be another field type other than varchar(255) to contain this type of data (an array of numbers, after all)
Is there a GOOD and efficient way of doing this? my method works for small tables, yes, but if the table grows.. (say, 10k rows, 50k, 300k ... ) this is obviously a problem.
The function that you want is find_in_set():
SELECT *
FROM table_a
WHERE find_in_set(33, tags) > 0;
You can simplify your like statement to be:
SELECT *
FROM table_a
WHERE concat(',', tags, ',') LIKE '%,33,%';
Neither of these can make use of an index. Having a separate table with one row per entity and per tag is the right way to go (but I think you know this already).

MySQL Sounds like to ignore 'The,a' etc

I have a table which includes names and each have a unique itemcode field, however I also have another table which we use as the root table for everything, this extra table is an extra I've recently added.
Because the names in my root table differ from the names in this new table, I need a bridge table, which I've created using a query which performs a INSERT..SELECT where the name in one table is equal to another. This is great, however it's limited my results because some names include The or A at the beginning so I'm missing them. So now I've changed my a = b query to a SOUNDS LIKE however that's only included names with differences at the end.
What I'm looking for is a way of ignoring a certain set of words such as:
The
A
Be
And
Etc and use the rest of the name? I can't do a 'LIKE %%' because that would capture too much.
You can remove the words The, A, Be etc by using the like statement. Ensure you have spaces on either side of the search terms so that it matches whole words, and not partial words.
SELECT * FROM namestable where names Like '% The %'

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.

MYSQL / SQL 'Exclude' or 'Except'

I want to query everything, Like:
SELECT * FROM
but I want to exclude two columns because their not necessary, but there's too many columns I need to just type it all one by one. Is there an exclude keyword or except keyword or something in SQL or MYSQL?
No. It's better practice to type out all of the fields as opposed to SELECT * FROM ... anyway.
If you're going to be a programmer, you may as well get used to typing :)
Yes, you must type them all out.
Or, if there really are that many you can do it programatically.
SHOW COLUMNS FROM `tablename`
Will give you the list of columns. Use whatever language you are using to pull them out and build the query with them.
Of course, you have to make sure the column names are escaped (what if you have a column name called select?).