Get result from Postgres query contains only English word and letters - postgresql

I have a Postgres query that returns a column that contains multiple language words. I want to get only the results those contains A-Z and 0-9 only. How can I get the result?
Select name from table;

This should do:
SELECT name FROM table WHERE name ~* '\A[A-Z0-9]*\Z';
If you only want uppercase letters (not clear from your question), then use the case sensitive regular expression operator:
SELECT name FROM table WHERE name ~ '\A[A-Z0-9]*\Z';
If you want at least one character, i.e. you don't want empty strings, change the * to +.

Related

Select column name containing forward slash in PostgreSQL

I am new to PostgreSQL and trying the below two scenarios:
Select a column name which already has a forward slash(/) in database (Road/Highway)
Using case on same column along with index
Select Road/Highway,
case
when index(upcase(Road/Highway), 'xturn') > 0 then 2
else 0
end as preferred_road
from abc_data;
But I am getting syntax error near index and for slash it is only taking Road.
Generally / means "division", so your column name is non-standard, much like working with keyword column names, column names with special characters must be quoted with double quotes. Use "Road/Highway" when referring to the column.

Where Column like '%__2017%' is returning columns with _2017

I have a table with a number of file names that have a date time stamp added to the file name. Unfortunately the process for creating the filenames is not consistent so I end up with names like,
RandomFilename__20170622_013633.csv
Some_other_Filename__20170621_015423.csv
YET-Another-Filename_20170605_010005.csv
Eventually I would like a select statement I would like to strip out the characters after filename and before the _timestamp and __timestamp. Ideally my select statement would remove the unwanted characters using LEFT() and CHARINDEX().
The below query is returning unexpected results
SELECT [Name]
FROM FileList
WHERE NAME like '%__2017%'
I get filenames with just a single underscore as well. This is throwing off my charindex for '__2017' and '_2017'.
Here is the current query I'm using to try and strip out the unwanted timestamp characters from the name column.
SELECT top 100 [Name]
,CASE
WHEN NAME like '%__2017%' then LEFT(NAME,CHARINDEX('_201',name) - 2)
WHEN NAME like '%_2017%' then LEFT(NAME,CHARINDEX('_201',name) - 1)
END AS ShortName
FROM [dbo].[FilesHistory]
Unfortunately this strips the filenames with a single underscore by 1 character too many, i.e. YET-Another-Filenam

Taking the prefix of a column value in PostgreSQL

I want to select a column value and trim away a suffix matching a regular expression, all inside PostgreSQL, how can this be done?
-- somewhat like performing s/_bar$// on "foo_bar"
select regexp_replace('foo_bar', '_bar$', '')

How to make "case-insensitive" query in Postgresql?

Is there any way to write case-insensitive queries in PostgreSQL, E.g. I want that following 3 queries return same result.
SELECT id FROM groups where name='administrator'
SELECT id FROM groups where name='ADMINISTRATOR'
SELECT id FROM groups where name='Administrator'
Use LOWER function to convert the strings to lower case before comparing.
Try this:
SELECT id
FROM groups
WHERE LOWER(name)=LOWER('Administrator')
using ILIKE instead of LIKE
SELECT id FROM groups WHERE name ILIKE 'Administrator'
The most common approach is to either lowercase or uppercase the search string and the data. But there are two problems with that.
It works in English, but not in all languages. (Maybe not even in
most languages.) Not every lowercase letter has a corresponding
uppercase letter; not every uppercase letter has a corresponding
lowercase letter.
Using functions like lower() and upper() will give you a sequential
scan. It can't use indexes. On my test system, using lower() takes
about 2000 times longer than a query that can use an index. (Test data has a little over 100k rows.)
There are at least three less frequently used solutions that might be more effective.
Use the citext module, which mostly mimics the behavior of a case-insensitive data type. Having loaded that module, you can create a case-insensitive index by CREATE INDEX ON groups (name::citext);. (But see below.)
Use a case-insensitive collation. This is set when you initialize a
database. Using a case-insensitive collation means you can accept
just about any format from client code, and you'll still return
useful results. (It also means you can't do case-sensitive queries. Duh.)
Create a functional index. Create a lowercase index by using CREATE
INDEX ON groups (LOWER(name));. Having done that, you can take advantage
of the index with queries like SELECT id FROM groups WHERE LOWER(name) = LOWER('ADMINISTRATOR');, or SELECT id FROM groups WHERE LOWER(name) = 'administrator'; You have to remember to use LOWER(), though.
The citext module doesn't provide a true case-insensitive data type. Instead, it behaves as if each string were lowercased. That is, it behaves as if you had called lower() on each string, as in number 3 above. The advantage is that programmers don't have to remember to lowercase strings. But you need to read the sections "String Comparison Behavior" and "Limitations" in the docs before you decide to use citext.
You can use ILIKE. i.e.
SELECT id FROM groups where name ILIKE 'administrator'
You can also read up on the ILIKE keyword. It can be quite useful at times, albeit it does not conform to the SQL standard. See here for more information: http://www.postgresql.org/docs/9.2/static/functions-matching.html
You could also use POSIX regular expressions, like
SELECT id FROM groups where name ~* 'administrator'
SELECT 'asd' ~* 'AsD' returns t
use ILIKE
select id from groups where name ILIKE 'adminstration';
If your coming the expressjs background and name is a variable
use
select id from groups where name ILIKE $1;
Using ~* can improve greatly on performance, with functionality of INSTR.
SELECT id FROM groups WHERE name ~* 'adm'
return rows with name that contains OR equals to 'adm'.
ILIKE work in this case:
SELECT id
FROM groups
WHERE name ILIKE 'Administrator'
For a case-insensitive parameterized query, you can use the following syntax:
"select * from article where upper(content) LIKE upper('%' || $1 || '%')"
-- Install 'Case Ignore Test Extension'
create extension citext;
-- Make a request
select 'Thomas'::citext in ('thomas', 'tiago');
select name from users where name::citext in ('thomas', 'tiago');
If you want not only upper/lower case but also diacritics, you can implement your own func:
CREATE EXTENSION unaccent;
CREATE OR REPLACE FUNCTION lower_unaccent(input text)
RETURNS text
LANGUAGE plpgsql
AS $function$
BEGIN
return lower(unaccent(input));
END;
$function$;
Call is then
select lower_unaccent('Hôtel')
>> 'hotel'
A tested approach is using ~*
As in the example below
SELECT id FROM groups WHERE name ~* 'administrator'
select id from groups where name in ('administrator', 'ADMINISTRATOR', 'Administrator')

Omitting the double quote to do query on PostgreSQL

Simple question, is there any way to omit the double quote in PostgreSQL?
Here is an example, giving select * from A;, I will retrieve ERROR: relation "a" does not exist, and I would have to give select * from "A"; to get the real result.
Is there any way not to do the second and instead do the first on PostgreSQL?
Your problem with this query started when you created your table. When you create your table, don't use quotes.
Use this:
CREATE TABLE a ( ... );
Not this:
CREATE TABLE "A" ( ... );
The latter will make it so that you always have to quote it later. The former makes it a normal name and you can use SELECT * FROM a; or SELECT * FROM A;
If you can't just recreate your table, use the ALTER TABLE syntax:
ALTER TABLE "A" RENAME TO a;
double quotes are required if you include capital letters in your table name in postgres
to avoid the requirements name your table "a"
Postgresql has some particular behaviour in regard to quoting and case sentivity: it folds every non-quoted identifier to lower case (also at creation time) and then works case-sensitively.
Double quotes in identifiers are only needed when the identifier (table name, column name, etc) was defined (at schema creation time) with uppercase letters (some or all) and between double quotes.
In that case (which I advice against), when you use that identifier, you must type it in the same way: case sensitively (type upper/lower case letter exactly as defined) and between double quotes.
In other cases, you can use non-quoted identifiers and work always case-insensitively.
Don't use upper case letter in your table name or it's column name, if you are using such thing then the postgres will required double quote for accessing it.
Please see the detailed description of what is happening here.
The PostgreSQL server table names are case-sensitive, but forced to be lower-case by default: when you type CREATE TABLE AAA, it will become CREATE TABLE aaa before the query execution.
Double-quoted names keep their case as it was, so after CREATE TABLE "AaA" you get the table AaA and have to write it double-quoted again and again.
Have no idea why did they do so :)