Ignore special characters in the WHERE clause - sql

I have a table named artists with a record with the value 'Miró' in the name column. When I do this request:
SELECT "artists".* FROM "artists" WHERE name = 'Miró'
I have one result, so it works.
Now, when I do this request (without the special ó) :
SELECT "artists".* FROM "artists" WHERE name = 'Miro'
I don't find anything. I want to ignore the special char. Is there a way to do it?
I have postgres 9.1.9.

For a more targeted pattern matching, you can use the function unaccent(), provided by the additional module unaccent:
SELECT * FROM artists WHERE unaccent(name) = 'Miro';
To make this fast, create a functional index. You have to overcome the obstacle that the function is only STABLE, not IMMUTABLE. I wrote a comprehensive answer with instructions (including installation) and links recently:
Does PostgreSQL support "accent insensitive" collations?

You could try using LIKE instead...
SELECT "artists".* FROM "artists" WHERE name like 'Mir%'

Related

How can I select all the occurence of a Username with numbers at the end?

I'm trying to create a request to find all the occurence of a name in my Usernames table:
for example I have:
SAnderso
BBobby
SAnderso1
SAnderso2
SAnderso99
and I'd like to get all the SAnderso(here 1,3,4,5)
here's what I tried:
SELECT * FROM Utilisateur WHERE NomUtilisateur LIKE 'SAnderso%[0123456789]' OR NomUtilisateur = 'SAnderso'
but when I do this nothing is shown in the results
can you help me ?
In any database, this might do want you want:
WHERE NomUtilisateur LIKE 'SAnderso%'
If you specifically need to check for numbers after the name, then the method depends on the database. In most databases, you'll need to use the extension for regular expressions.
In previous questions you have asked about MySQL so, assuming MySQL, you can use REGEXP_LIKE which allows regular expressions to be used:
SELECT * FROM Utilisateur
WHERE REGEXP_LIKE(NomUtilisateur, '^(SAnderso|SAnderso.*[0-9])$')
This is based on your attempt where you used % in LIKE so that there may be characters following "SAnderso" before the digit(s). If you only want "SAnderso" optionally followed by digits then you would change the regex pattern to ^SAnderso[0-9]*$
thanks to #mhawke who helped me find about REGEX in sql database the solution was to use it but in maria db REGEXP_LIKE does'nt exist so I looked on the documentation and foudn out I could do it like this:
SELECT * FROM Utilisateur WHERE NomUtilisateur REGEXP '^(SAnderso|SAnderso.*[0-9])$'

Can you use DOES NOT CONTAIN in SQL to replace not like?

I have a table called logs.lognotes, and I want to find a faster way to search for customers who do not have a specific word or phrase in the note. I know I can use "not like", but my question is, can you use DOES NOT CONTAINS to replace not like, in the same way you can use:
SELECT *
FROM table
WHERE CONTAINS (column, ‘searchword’)
Yes, you should be able to use NOT on any boolean expression, as mentioned in the SQL Server Docs here. And, it would look something like this:
SELECT *
FROM table
WHERE NOT CONTAINS (column, ‘searchword’)
To search for records that do not contain the 'searchword' in the column. And, according to
Performance of like '%Query%' vs full text search CONTAINS query
this method should be faster than using LIKE with wildcards.
You can also simply use this:
select * from tablename where not(columnname like '%value%')

Is there a PostgreSQL setting that I can use to do case-insensitive queries on column values?

I have been using MySQL for 9 years and now have a new Rails 3.2 application in which I am using PostgreSQL. I am getting bitten by a couple of assumptions that I am bringing to the project.
With MySQL, I could set database settings so that this:
plan = Plan.find_by_name("platinum")
would return a record, even if the value in the db was Platinum. With the default settings of PostgreSQL, it doesn't work like that.
I'm sure this must be a common issue. I sure don't want my customers having to type in exact matches to case. I can't find anything online for some reason, I am just turning up 10-year old support cases on PostgreSQL's website in which this feature is not supported. Hopefully it has changed by now.
Solved:
Thanks to the answer below, here is how to accomplish this:
In Postgres 9.1+, the citext contrib module is shipped with the code. All you need to do is type this at the psql command line:
create extension citext
Now you can create a table with the citext column type:
create table people (name ctext);
Insert some rows to test:
insert into people (name) values ('ADRIAN');
insert into people (name) values ('adrian');
And test:
select * from people where name = 'Adrian';
Results:
name
--------
adrian
ADRIAN
(2 rows)
You can define the column as citext with the citext contrib module.
Another option is to use ilike with no wildcards. This will still use a b-tree index if one is present, at least a text_pattern_ops index if not a default btree. You'll need to escape the LIKE expression metacharacters documented in pattern matching to prevent accidental wildcard searches.
Personally I'm really hoping to see a COLLATE option for case insensitivity added now that per-expression COLLATE is supported... but right now, that's hand-waving future stuff.

SQL wildcard issue

I have a database which can be modified by our users through an interface. For one field (companyID) they should have the ability to place an asterisk in the string as a wildcard character.
For example, they can put in G378* to stand for any companyID starting with G378.
Now on my client program I'm providing a "full" companyID as a parameter:
SELECT * FROM table WHERE companyID = '" + myCompanyID + "'
But I have to check for the wildcard, is there anything I can add to my query to check for this. I'm not sure how to explain it but it's kinda backwards from what I'm used to. Can I modify the value I provide (the full companyID) to match the wildcard value from in the query itself??
I hope this maked sense.
Thanks!
EDIT: The user is not using SELECT. The user is only using INSERT or UPDATE and THEY are the ones placing the * in the field. My program is using SELECT and I only have the full companyID (no asterisk).
This is a classic SQL Injection target! You should be glad that you found it now.
Back to your problem, when users enter '*', replace it with '%', and use LIKE instead of = in your query.
For example, when end-users enter "US*123", run this query:
SELECT * FROM table WHERE companyID LIKE #companyIdTemplate
set #companyIdTemplate parameter to "US%123", and run the query.
I used .NET's # in the example, but query parameters are denoted in ways specific to your hosting language. For example, they become ? in Java. Check any DB programming tutorial on use of parameterized queries to find out how it's done in your system.
EDIT : If you would like to perform an insert based on a wildcard that specifies records in another table, you can do an insert-from-select, like this:
INSERT INTO CompanyNotes (CompanyId, Note)
SELECT c.companyId, #NoteText
FROM Company c
WHERE c.companyId LIKE 'G378%'
This will insert a record with the value of the #NoteText parameter into CompanyNotes table for each company with the ID matching "G378%".
in TSQL I would use replace and like. ie:
select * from table where companyid like replace(mycompanyid,'*','%');
This is somewhat implementation dependant and you did not mention which type of SQL you are dealing with. However, looking at MS SQL Server wildcards include % (for any number of characters) or _ (for a single character). Wildcards are only evaluated as wildcards when used with "like" and not an = comparison. But you can pass in a paramater that includes a wildcard and have it evaluated as a wildcard as long as you are using "like"

SQL Contains - only match at start

For some reason I cannot find the answer on Google! But with the SQL contains function how can I tell it to start at the beginning of a string, I.e I am looking for the full-text equivalent to
LIKE 'some_term%'.
I know I can use like, but since I already have the full-text index set up, AND the table is expected to have thousands of rows, I would prefer to use Contains.
Thanks!
You want something like this:
Rather than specify multiple terms, you can use a 'prefix term' if the
terms begin with the same characters. To use a prefix term, specify
the beginning characters, then add an asterisk (*) wildcard to the end
of the term. Enclose the prefix term in double quotes. The following
statement returns the same results as the previous one.
-- Search for all terms that begin with 'storm'
SELECT StormID, StormHead, StormBody FROM StormyWeather
WHERE CONTAINS(StormHead, '"storm*"')
http://www.simple-talk.com/sql/learn-sql-server/full-text-indexing-workbench/
You can use CONTAINS with a LIKE subquery for matching only a start:
SELECT *
FROM (
SELECT *
FROM myTable WHERE CONTAINS('"Alice in wonderland"')
) AS S1
WHERE S1.edition LIKE 'Alice in wonderland%'
This way, the slow LIKE query will be run against a smaller set
The only solution I can think of it to actually prepend a unique word to the beginning of every field in the table.
e.g. Update every row so that 'xfirstword ' appears at the start of the text (e.g. Field1). Then you can search for CONTAINS(Field1, 'NEAR ((xfirstword, "TERM*"),0)')
Pretty crappy solution, especially as we know that the full text index stores the actual position of each word in the text (see this link for details: http://msdn.microsoft.com/en-us/library/ms142551.aspx)
I am facing the similar issue. This is what I have implemented as a work around.
I have made another table and pulled only the rows like 'some_term%'.
Now, on this new table I have implemented the FullText search.
Please do inform me if you tried some other better approach