replace substring for particular position in postgres - postgresql

I have a table and want update query to update dob
------------
dob
------------
19101984
19111984
19071985
19081985
19101985
19121985
I want to remove sub string from position 5 to character length of 2 means in the result table will be :
------------
dob
------------
191084
191184
190785
190885
191085
191285

Use regex_replace:
select regexp_replace(dob::text, '(\d{4})\d{2}(\d{2})', E'\\1\\2')
from your_table;
For updating:
update your_table
set dob = regexp_replace(dob, '(\d{4})\d{2}(\d{2})', E'\\1\\2');
The regex pattern being used here is:
(\d{4})\d{2}(\d{2})
^^^^ ^^^^ <-- capture groups
The first four and last two digits are captured in groups 1 and 2, respectively. Then, we simply replace with the first and second capture group.
It is not clear whether the dob column is text or not. If it is numeric, then you should be able to cast to text and run the above query.
Demo

Related

select a column name with a variable

i have a table with 10 columns ,with names: cost201907, cost201906, cost201905 ......
I want to put in a variable the today month and year: a = 201907
define a = to_char(SYSDATE, 'yyyy')|| to_char(SYSDATE, 'mm') from dual;
SELECT &a;
output: a = 201907
My goal is to select a column using this variable.
Each month run a script that give me today's date in a variable,
and after use it to select the most recent columns with a select statement, such as:
Select 'cost'||a from Table1.
Probably i ll use PL/SQL but still cant find a way. Please help me.
You can use a substitution variable, but you need to populate it slightly differently, form the column name properly.
At the moment you're using define, which gives a the value of the entire string you set; then your select gets that whole string as a replacement, which you can see with set verify on:
SELECT &a;
old:SELECT &a
new:SELECT to_char(SYSDATE, 'yyyy')|| to_char(SYSDATE, 'mm') from dual
TO_CHA
------
201907
Then when you do
Select 'cost'a from Table1;
you are selecting the text literal 'cost', and giving that column expression the alias a - completely unrelated to your variable; so you'll see output like:
A
----
cost
cost
cost
...
with one output row for every row in your table.
Instead of your define, use the column ... new_value ... option to make the result of a dummy query available as a substitution variable for a later one:
column a new_value a;
select to_char(sysdate, 'YYYYMM') as a from dual;
A
------
201907
select cost&a from table1;
old:select cost&a from table1
new:select cost201907 from table1
COST201907
----------
42
...
You can wrap the dummy query in a set termout off and ... on pair, though you still seem to need to run your script from a file with # to make that take effect properly. And you can set verify off to hide the old/new display once you're happy with it.

pgSQL: select first occurrence of the number inside a string

String contains numeric and alphabetic data. what is the way to pick up only number? for example:
for the string "abc-123a-66" select should return "123"
You could use regexp_matches
CREATE table foo (
test VARCHAR);
INSERT INTO foo VALUES('abc-123a-66');
SELECT (regexp_matches(test, '\d+'))[1] FROM foo;
Example at SQLFiddle
In PostgreSQL this can be done with:
SELECT regexp_matches(regexp_replace(whatever_columnn,'\D*',''),'\d+') FROM whatever_table;
The first function (regexp_replace) deletes every non digit from the beginning of the string, the second (regexp_matches) extracts one or more occurrences of any digit from the output of the first function.

PostgreSQL : Update column with same vaue

Following is sample table and data
create table chk_vals (vals text);
insert into chk_vals values ('1|2|4|3|9|8|34|35|38|1|37|1508|1534');
So,How to update column vals by appending integer in 4th position of the existing value(ie. 3 | is used as a seperator) into the last position along with symbol |
as you can see the existsing value if 1|2|4|3|9|8|34|35|38|1|37|1508|1534 and the output should be 1|2|4|3|9|8|34|35|38|1|37|1508|1534|3
Use PostgreSQL's split_part() to splits the field and find the value at position 4
select split_part(vals,'|',4) val from chk_vals
this will return value 3
update chk_vals
set vals=vals||format('|%s',(select split_part(vals,'|',4) val from chk_vals))
Format()

Get substring into a new column

I have a table that contains a column that has data in the following format - lets call the column "title" and the table "s"
title
ab.123
ab.321
cde.456
cde.654
fghi.789
fghi.987
I am trying to get a unique list of the characters that come before the "." so that i end up with this:
ab
cde
fghi
I have tried selecting the initial column into a table then trying to do an update to create a new column that is the position of the dot using "ss".
something like this:
t: select title from s
update thedot: (title ss `.)[0] from t
i was then going to try and do a 3rd column that would be "N" number of characters from "title" where N is the value stored in "thedot" column.
All i get when i try the update is a "type" error.
Any ideas? I am very new to kdb so no doubt doing something simple in a very silly way.
the reason why you get the type error is because ss only works on string type, not symbol. Plus ss is not vector based function so you need to combine it with each '.
q)update thedot:string[title] ss' "." from t
title thedot
---------------
ab.123 2
ab.321 2
cde.456 3
cde.654 3
fghi.789 4
There are a few ways to solve your problem:
q)select distinct(`$"." vs' string title)[;0] from t
x
----
ab
cde
fghi
q)select distinct(` vs' title)[;0] from t
x
----
ab
cde
fghi
You can read here for more info: http://code.kx.com/q/ref/casting/#vs
An alternative is to make use of the 0: operator, to parse around the "." delimiter. This operator is especially useful if you have a fixed number of 'columns' like in a csv file. In this case where there is a fixed number of columns and we only want the first, a list of distinct characters before the "." can be returned with:
exec distinct raze("S ";".")0:string title from t
`ab`cde`fghi
OR:
distinct raze("S ";".")0:string t`title
`ab`cde`fghi
Where "S " defines the types of each column and "." is the record delimiter. For records with differing number of columns it would be better to use the vs operator.
A variation of WooiKent's answer using each-right (/:) :
q)exec distinct (` vs/:x)[;0] from t
`ab`cde`fghi

Adding leading zero if length is not equal to 10 digit using sql

I am trying to join 2 tables but my problem is that one of the table has 10 digit number and the other one may have 10 or less digit number. For this reason, i am loosing some data so i would like to do is check the length first if the length is less than 10 digit then i want to add leading zeros so i can make it 10 digit number. I want to do this when i am joining this so i am not sure if this is possible. Here is an example if i i have 251458 in the TABLE_WITHOUT_LEADING_ZERO then i want to change it like this: 0000251458. Here is what i have so far:
select ACCT_NUM, H.CODE
FROM TABLE_WITH_LEEDING_ZERO D, TABLE_WITHOUT_LEADING_ZERO H
WHERE substring(D.ACCT_NUM from position('.' in D.ACCT_NUM) + 2) = cast (H.CODE as varchar (10))
thanks
Another alternative:
SELECT TO_CHAR(12345,'fm0000000000');
to_char
------------
0000012345
In Netezza you can use LPAD:
select lpad(s.sample,10,0) as result
from (select 12345 as sample) s
result
-------
0000012345
However it would be more efficient to remove the zeros like in the example below:
select cast(trim(Leading '0' from s.sample) as integer) as result
from (select '0000012345' as sample) s
result
-------
12345