I have a question about concat function in PostgreSQL.
This sentence works well in MySQL:
SELECT * FROM words
WHERE CONCAT (word,' ',gender,' ',semantic) LIKE '%"+value+"%'.
Value is a variable that is changed inside my Java program.
But I need the same working in postgresql. How kann I concatenate inside the WHERE clause, using postgres, considering the variable "value" that will have its value changed ?
In Postgresql you concatenate using the following syntax:
(users.first_name || ' ' || users.last_name)
Reference: http://www.postgresql.org/docs/9.1/static/functions-string.html
You can also use this for postgresql:
concat_ws(' ', campo1, campo2) like '%value%'
Note that there is a space between single quotes
Related
I inserted a bunch of rows with a text field like content='...\n...\n...'.
I didn't use e in front, like conent=e'...\n...\n..., so now \n is not actually displayed as a newline - it's printed as text.
How do I fix this, i.e. how to change every row's content field from '...' to e'...'?
The syntax variant E'string' makes Postgres interpret the given string as Posix escape string. \n encoding a newline is only one of many interpreted escape sequences (even if the most common one). See:
Insert text with single quotes in PostgreSQL
To "re-evaluate" your Posix escape string, you could use a simple function with dynamic SQL like this:
CREATE OR REPLACE FUNCTION f_eval_posix_escapes(INOUT _string text)
LANGUAGE plpgsql AS
$func$
BEGIN
EXECUTE 'SELECT E''' || _string || '''' INTO _string;
END
$func$;
WARNING 1: This is inherently unsafe! We have to evaluate input strings dynamically without quoting and escaping, which allows SQL injection. Only use this in a safe environment.
WARNING 2: Don't apply repeatedly. Or it will misinterpret your actual string with genuine \ characters, etc.
WARNING 3: This simple function is imperfect as it cannot cope with nested single quotes properly. If you have some of those, consider instead:
Unescape a string with escaped newlines and carriage returns
Apply:
UPDATE tbl
SET content = f_eval_posix_escapes(content)
WHERE content IS DISTINCT FROM f_eval_posix_escapes(content);
db<>fiddle here
Note the added WHERE clause to skip updates that would not change anything. See:
How do I (or can I) SELECT DISTINCT on multiple columns?
Use REPLACE in an update query. Something like this: (I'm on mobile so please ignore any typo or syntax erro)
UPDATE table
SET
column = REPLACE(column, '\n', e'\n')
Long story...
I am trying to geenrate a crosstab query dynamically and run it as a psql script..
To achieve this, I want the last line of the sql to generated and appended to the top portion of the sql.
The last line of the sql is like this.... "as final_result(symbol character varying,"431" numeric,"432" numeric,"433" numeric);"
Of which, the "431", "432" etc are to be generated dynamically as these are the pivot columns and they change from time to time...
So I wrote a query to output the text as follows....
psql -c "select distinct '"'||runweek||'" numeric ,' from calendar where runweek between current_runweek()-2 and current_runweek() order by 1;" -U USER -d DBNAME > /tmp/gengen.lst
While the sql provides the output, when I run it as a script, because of the special characters (', "", ) it fails.
How should I get it working? My plan was then loop through the "lst" file and build the pivot string, and append that to the top portion of the sql and execute the script... (New to postgres, does not know , dynamic sql generation and execution etc.. but I am comfortable with UNIX scripting..)
If I could somehow get the output as
("431" numeric, "432" numeric....etc) in a single step, if there is a recommendation to achieve this, it will be greatly appreciated.....
Since you're using double quotes around the argument, double quotes inside the argument must be escaped with a backslash:
psql -c "select distinct '\"'||runweek||'\" numeric ,' from calendar where runweek between current_runweek()-2 and current_runweek() order by 1;"
Heredoc can also be used instead of -c. It accepts multi-line formatting so that makes the whole thing more readable.
(psql [arguments] <<EOF
select distinct '"'||runweek||'" numeric ,'
from calendar
where runweek between current_runweek()-2 and current_runweek()
order by 1;
EOF
) > output
By using quote_ident which is specifically meant to produce a quoted identifier from a text value, you don't even need to add the double quotes. The query could be like:
select string_agg( quote_ident(runweek::text), ',' order by runweek)
from calendar
where runweek between current_runweek()-2 and current_runweek();
which also solves the problem that your original query has a stray ',' at the end, whereas this form does not.
I need to do an UPDATE script using the Replace() function of Postgres but I don't know the exact string that I have to replace and I'd like to know if there is some way that I can do this similary the LIKEoperator, using Wildcards.
My problem is that I got a table that contains some scripts and at the end of each one there is a tag <signature> like this:
'SELECT SCRIPT WHATEVER.... < signature>782798e2a92c72b270t920b< signature>'
What I need to do is:
UPDATE table SET script = REPLACE(script,'<signature>%<signature>','<signature>1234ABCDEF567890<signature>')
Whatever the signature is, I need to replace with a new one defined by me. I know using the '%' doesn't work, it was just to ilustrate the effect i want to perform. Is there any way to do this in Postgres 9.5?
with expr
as
(select 'Hello <signature>thisismysig</signature>'::text as
full_text, '<signature>'::text as open,
'</signature>'::text as close
)
select
substring(full_text from
position(open in full_text)+char_length(open)
for
position(close in full_text)- char_length(open)-position(open in full_text)
)
note: with part added for ease of understanding (hopefully).
Use POSIX regex to do the same thing as other answer (but shorter)
select
substring('a bunch of other stuff <signature>mysig</signature>'
from '<signature>(.*?)</signature>')
I'm trying to use SELECT regexp_replace(m.*, '[\n\r]+', ' ', 'g') to remove carriage returns and new lines from my field to generate a CSV from my table; however, looks like my postgresql version (7.4.27) does not support that function.
function regexp_replace(members, "unknown", "unknown", "unknown") does not exist
I also tried doing it this way:
SELECT replace(replace(m.*, '\r', ''), '\n', '')
function replace(members, "unknown", "unknown") does not exist
No function matches the given name and argument types. You may need to add explicit type casts.
or this way:
SELECT replace(replace(m.*, chr(13), ''), chr(10), '')
function replace(members, text, "unknown") does not exist
and still got similar errors.
How can a achieve that using another function or solution?
m.* makes no sense where you put it. It would work like this:
SELECT replace(replace(m.some_column, chr(13), ''), chr(10), '')
FROM tbl m;
But that just removes all "linefeed" and "carriage return" characters completely instead of replacing each string consisting only of these characters with a single space character like your original. If that's what you want, single character replacement is simpler and cheaper with translate() - also available in ancient pg 7.4:
SELECT translate(some_column, chr(13) || chr(10), '');
To achieve what your original regexp_replace() does (just without the nonsensical m.*), identify a single character that's not in the string and use that as stepping stone. Say: ° does not pop up, then:
SELECT replace(replace(replace(
translate(some_column, chr(13) || chr(10), '°') -- replace with dummy
, '°°', '°') -- consolidate to single dummy
, '°°', '°') -- repeat as many times as necessary
, '°', ' '); -- replace dummy with space
Looks awkward, and it's imperfect: fails for too many consecutive line breaks. But it's probably still faster than regexp_replace(), even in modern Postgres, because regular expressions are much more expensive. Then again, performance is probably not an issue here.
Upgrade to modern Postgres and you don't need this.
I've got a list 400 rows +. Each row looks similar to this: example-example123 I would like to remove everything past '-' so that I'm left with just the beginning part: example123
Any help would be greatly appreciated.
try it like this:
UPDATE table SET column_name=LEFT(column_name, INSTR(column_name, '-')-1)
WHERE INSTR(column_name, '-')>0;
If you only want to select you do it this way:
SELECT LEFT(column_name, INSTR(column_name, '-')-1) FROM table;
INSTR function gets you the position of your - then you update the column value to become from the first letter of the string till the position of the - -1
Here's a fiddle
You can use SQL Trim() function
SELECT TRIM(TRAILING '-' FROM BHEXLIVESQLVS1-LIVE61MSSQL)
AS TRAILING_TRIM
FROM table;
The result should be "BHEXLIVESQLVS1"
select SUBSTRING(col_name,0,Charindex ('-',col_name))
Assuming you need to do this in a query, you can use the string functions of your database.
For DB2 this would look something like
select SUBSTR(YOURCOLUMN, 1, LOCATE('-',YOURCOLUMN)) from YOURTABLE where ...
In SQL Server you could use
SUBSTRING
and
CHARINDEX
For SQL server you can do this,
LEFT(columnName, charindex('-', columnName)) to remove every character after '-'
to remove the special character as well do this,
LEFT(columnName, charindex('-', columnName)-1)
SELECT SUBSTRING(col_name,0,Charindex ('-',col_name)) FROM table_name
WHERE col_name='yourvalue'
Eg.
SELECT SUBSTRING(TPBS_Path,0,Charindex ('->',TPBS_Path)) FROM [CFG].[CFG_T_Project_Breakdown_Structure] WHERE TPBS_Parent_PBS_Code='LE180404'
here TPBS_Path is the column for which trim is to be done and [CFG].[CFG_T_Project_Breakdown_Structure] is table name and TPBS_Parent_PBS_Code='LE180404' is the select condition. Everything after '->' will be trimmed