MySQL Sounds like to ignore 'The,a' etc - mysql

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 %'

Related

How to search in parts of entries within a mysql database?

I'm working with a database that contains some "special" columns:
There are "cells" of a table containing a single Name of e.g. a painter like "Turner, William"; some other contain an ID like "ID123" connected with a table of persons.
But some cells contain two or more entries, like: "ID123 ; Turner, William" - they are always separated by ";"
My question is:
Normaly I can use something like "SELECT - FROM - LEFT JOIN" for simple selections with one entry. Is there any possibility for working with more than one entry?
Something like
SELECT artwork.nameid, artwork.artist,
person.fullname
FROM artworks
LEFT JOIN person ON person.id = [Part of String artwork.artist]
One of the important principles of a relational database is that each column contains a single value, not a composite value like you describe. And the values in a given column have the same type, not variable types.
So you should solve your problem by having two columns, one for an ID and the other for a Name. Don't try to store them together in the same column with a semicolon separator.
CREATE TABLE artworks (
...
PersonID VARCHAR(5), -- example: ID123
Name VARCHAR(100), -- example: Turner, William
...
);
That said, you might be able to do what you describe using some MySQL string functions.
For example you can use LOCATE(';' artwork.artst) to detect if there's a semicolon present in a given string. You can use SUBSTRING_INDEX(artwork.artist, ';', 2) to extract the second "field" from a semicolon-separate field.
The expression needed to solve your problem is bound to become terribly complex if you need to handle a variety of cases, like what if a column has the ID first instead of second? What if there are three or more fields separated by semicolons?
Please take the recommendation that it will be far easier to restructure your table so you always have one value in each column.

Search for specific keyword in MYSQL

I'm almost new to mysql.
I wanted to write a query to search for specific keywords in a column where keywords are separated by the comma. but as I use the following code, it only returns the rows where I only have that specific keyword, not in combination with any other keywords.
In Table q16, I'm looking for a way to select rows that have my keyword in the "Area_of_concern" column, no matter if it's combined with other keywords or not:
SELECT *
FROM `q16`
WHERE area_of_concern like '%more education is needed%'
Here's an input example:
q16_id area of concern
1 more education is needed
2 more enforcement, change in strategy
3 change in strategy
4 more education is needed, change in strategy
5 transportation issue, more enforcement, more education is needed
Where I'm looking to get the rows with the keyword "more education is needed". So I should see row 1, 4,5 in the output
I think you should create a table where you have one column for keywords and one column for where those keywords are used: a foreign key for the q16 table in your case.
It will work much faster that way.
As for your question it is a duplicate of this one here, I believe.
How to search for rows containing a substring?
A quick try: try using double quotes instead of single ones, as in some systems, single quotes don't allow for escapes (special characters) inside them.

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).

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

mysql keyword search across multiple columns

Various incarnations of this question have been asked here before, but I thought I'd give it another shot.
I had a terrible database layout. A single entity (widget) was split into two tables:
CREATE TABLE widgets (widget_id int(10) NOT NULL auto_increment)
CREATE TABLE widget_data (
widget_id int(10),
field ENUM('name','size','color','brand'),
data TEXT)
this was less that ideal. if wanted to find widgets of a specific name, color and brand, i had to do a three-way join on the widget_data table. so I converted to the reasonable table type:
CREATE TABLE widgets (widget_id int(10) NOT NULL auto_increment,
name VARCHAR(32),size INT(3),color VARCHAR(16), brand VARCHAR(32))
This makes most queries much better. But it makes searching harder. It used to be that if i wanted to search widgets for, say, '%black%', I would just SELECT * FROM widget_data WHERE data LIKE '%black%'. This would give me all instances of widgets that are black in color, or are made by blackwell industries, or whatever. I would even know exactly which field matched, and could show that to my user.
how do I execute a similar search using the new table layout? I could of course do WHERE name LIKE '%black%' OR size LIKE '%black%'... but that seems clunky, and I still don't know which fields matched. I could run a separate query for each column I want to match on, which would give me all matches and how they matched, but that would be a performance hit. any ideas?
You can include part of WHERE expression into selecting columns. For example:
SELECT
*,
(name LIKE '%black%') AS name_matched,
(size LIKE '%black%') AS size_matched
FROM widget_data
WHERE name LIKE '%black%' OR size LIKE '%black%'...
Then check value of name_matched on side of the script.
Not sure how it will affect performance. Feal free to test it before going to production
You have two conflicting requirements. You want to search as if all your data is in a single field, but you also want to identify which specific field was matched.
There's nothing wrong with your WHERE name LIKE '%black%' OR size LIKE '%black%'... expression. It's a perfectly valid search on the table as you have defined it. Why not just check the results in code to see which one matched? It's a minimal overhead.
If you want a cleaner syntax for your SQL then you could create a view on the table, adding an extra field which consists of concatenating the other fields:
CREATE VIEW extra_widget_data AS
SELECT (name, size, color, brand,
CONCAT(name, size, color, brand) as all_fields)
FROM widget_data;
Then you'd have to add an index on this field, which requires more space, CPU time to maintain etc. I don't think it's worth it.
You probably want to look into MySQL full text search capability, this enables you to match against multiple columns of varchar type.
http://dev.mysql.com/doc/refman/5.1/en/fulltext-search.html