How to use inticap and leave last part in capital letter in postgresql 11 - postgresql

I have a table with address all in capital but I am trying to format it like this:
145 WELLBEING STREET, PARADE, LONDON, PP1 5PP
145 Wellbeing Street, Parade, London, PP1 5PP
How can i work with that? I have tried, converting all with initcap:
UPDATE address_table
SET field_address = initcap(field_address)
And then it pick the last piece and convert it in Uppercase:
UPDATE address_table
SET field_address = upper(regexp_replace(field_address , '^.*,', ''))
So i thought in concatenate but still i have the last piece in initcap...
I have also tried with :
SELECT field_address || upper(trim(reverse(split_part(reverse(field_address ), ',', 1)))) FROM address_table
but the results i got are like i.e.
Southridge, Newbury Hill, Hampstead Norreys, Thatcham, Rg18 0trRG18 0TR
How can i delete the last part after the last comma to convert it in capital?

From Postgres 14 :
UPDATE address_table
SET field_address = initcap(replace(field_address, split_part(field_address, ',', -1), '')) || split_part(field_address, ',', -1)
From Postgres 10 :
UPDATE address_table
SET field_address = initcap(regexp_replace(field_address, '[^,]+$', '')) || (regexp_match(field_address, '[^,]+$'))[1]
see test result in dbfiddle.

Related

Square brackets in PgAdmin 4 for null values

In pgAdmin 4, the column value is seen as a square bracket [...] instead of an empty value.
The column data type is character(4) and name is carr_desig_icao_cd. Database is postgreSql.
How to avoid the square brackets? I tried pgAdmin 4 preferences but no luck.
Thanks for your help.
Output from psql is as below:
Could it be something to do with converting to_char?
Here are results of my testing.
This query produced no brackets and dots:
select at1.score
This query produced brackets and dots
select to_char(at1.score, '999')
I noticed when this was downloaded and opened in Excel, there were no brackets but three spaces at the start of the column.
This query removed the brackets and dots in PgAdmin and removed the spaces after downloading to Excel:
select replace(to_char(at1.score, '999'), ' ', '')
Just noting also that this was a sub query as part of a bigger query that looked a bit like this:
select
cm.course_id
, us.user_id
, gm.title
, (select replace(to_char(at1.score * 20, '999'), ' ', '') || '% ' || to_char(at1.attempt_date, 'yyyy-mm-dd') from attempt at1 where at1.pk1 = gg.highest_attempt_pk1)
from
etc (joins of course_main cm, users us, gradebook_main gm, gradebook_grade gg, attempt at)
This screenshot shows before and after

PostgreSQL return last n words

How to return last n words using Postgres.
I have tried using LEFT method.
SELECT DISTINCT LEFT(name, -4) FROM my_table;
but it return last 4 characters ,i want to return last 3 words.
demo:db<>fiddle
You can do this using a the SUBSTRING() function and regular expressions:
SELECT
SUBSTRING(name FROM '((\S+\s+){0,3}\S+$)')
FROM my_table
This has been explained here: How can I match the last two words in a sentence in PostgreSQL?
\S+ is a string of non-whitespace characters
\s+ is a string of whitespace characters (e.g. one space)
(\S+\s+){0,3} Zero to three words separated by a space
\S+$ one word at the end of the text.
-> creates 4 words (or less if there are no more).
One way is to use regexp_split_to_array() to split the string into the words it contains and then put a string back together using the last 3 words in that array.
SELECT coalesce(w.words[array_length(w.words, 1) - 2] || ' ', '')
|| coalesce(w.words[array_length(w.words, 1) - 1] || ' ', '')
|| coalesce(w.words[array_length(w.words, 1)], '')
FROM mytable t
CROSS JOIN LATERAL (SELECT regexp_split_to_array(t."name", ' ') words) w;
db<>fiddle
RIGHT() should do
SELECT RIGHT('MYCOLUMN', 4); -- returns LUMN
UPD
You can convert to array and then back to string
SELECT array_to_string(sentence[(array_length(sentence,1)-3):(array_length(sentence,1))],' ','*')
FROM
(
SELECT regexp_split_to_array('this is the one of the way to get the last four words of the string', E'\\s+') AS sentence
) foo;
DEMO HERE

Extract string with multiple criteria - sql

We have a column of varying string values like below. How to extract part of the string and return the desired result in Redshift?
Example
Remove last part that starts with an underscore and number (_1_MN, number can be 1-1000)
Remove leading part (Ed_)
Replace any remaining underscore with a space
String:
Ed_Westside Ind School District 94_Williams Elementary School_1_MN
Desired result:
Westside Ind School District 94 Williams Elementary School
MySQL
UPDATE products
SET col = SUBSTRING(col FROM 3)
WHERE col LIKE ('Ed_%')
UPDATE products
SET col = SUBSTRING(col FROM -5 )
WHERE col LIKE ('%_1_MN')
UPDATE products
SET col = REPLACE(col, '_', ' ')
While not very elegant, this worked.
REGEXP_REPLACE(LEFT(RIGHT(name, LEN(name) - 3), LEN(name) -8) , '_', ' ')

Truncating leading zero from the string in postgresql

I'm trying to truncate leading zero from the address. example:
input
1 06TH ST
12 02ND AVE
123 001St CT
expected output
1 6TH ST
12 2ND AVE
123 1St CT
Here is what i have:
update table
set address = regexp_replace(address,'(0\d+(ST|ND|TH))','?????? need help here')
where address ~ '\s0\d+(ST|ND|TH)\s';
many thanks in advance
assuming that the address always has some number/letter address (1234, 1a, 33B) followed by a sequence of 1 or more spaces followed by the part you want to strip leading zeroes...
select substr(address, 1, strpos(address, ' ')) || ltrim(substr(address, strpos(address, ' ')), ' 0') from table;
or, to update the table:
update table set address = substr(address, 1, strpos(address, ' ')) || ltrim(substr(address, strpos(address, ' ')), ' 0');
-g
What you are looking for is the back references in the regular expressions:
UPDATE table
SET address = regexp_replace(address, '\m0+(\d+\w+)', '\1', 'g')
WHERE address ~ '\m0+(\d+\w+)'
Also:
\m used to match the beginning of a word (to avoid replacing inside words (f.ex. in 101Th)
0+ truncates all zeros (does not included in the capturing parenthesis)
\d+ used to capture the remaining numbers
\w+ used to capture the remaining word characters
a word caracter can be any alphanumeric character, and the underscore _.

Dynamic pivot - how to obtain column titles parametrically?

I wish to write a Query for SAP B1 (t-sql) that will list all Income and Expenses Items by total and month by month.
I have successfully written a Query using PIVOT, but I do not want the column headings to be hardcoded like: Jan-11, Feb-11, Mar-11 ... Dec-11.
Rather I want the column headings to be parametrically generated, so that if I input:
--------------------------------------
Query - Selection Criteria
--------------------------------------
Posting Date greater or equal 01.09.10
Posting Date smaller or equal 31.08.11
[OK] [Cancel]
the Query will generate the following columns:
Sep-10, Oct-10, Nov-10, ..... Aug-11
I guess DYNAMIC PIVOT can do the trick.
So, I modified one SQL obtained from another forum to suit my purpose, but it does not work. The error message I get is Incorrect Syntax near 20100901.
Could anybody help me locate my error?
Note: In SAP B1, '[%1]' is an input variable
Here's my query:
/*Section 1*/
DECLARE #listCol VARCHAR(2000)
DECLARE #query VARCHAR(4000)
-------------------------------------
/*Section 2*/
SELECT #listCol =
STUFF(
( SELECT DISTINCT '],[' + CONVERT(VARCHAR, MONTH(T0.RefDate), 102)
FROM JDT1
FOR XML PATH(''))
, 1, 2, '') + ']'
------------------------------------
/*Section 3*/
SET #query = '
SELECT * FROM
(
SELECT
T0.Account,
T1.GroupMask,
T1.AcctName,
MONTH(T0.RefDate) as [Month],
(T0.Debit - T0.Credit) as [Amount]
FROM dbo.JDT1 T0
JOIN dbo.OACT T1 ON T0.Account = T1.AcctCode
WHERE
T1.GroupMask IN (4,5,6,7) AND
T0.[Refdate] >= '[%1]' AND
T0.[Refdate] <= '[%2]'
) S
PIVOT
(
Sum(Amount)
FOR [Month] IN ('+#listCol+')
) AS pvt
'
--------------------------------------------
/*Section 4*/
EXECUTE (#query)
I don't know SAP, but a couple of things spring to mind:
It looks like you want #listCol to contain a collection of numbers within square brackets, for example [07],[08],[09].... However, your code appears not to put a [ at the start of this string.
Try replacing the lines
T0.[Refdate] >= '[%1]' AND
T0.[Refdate] <= '[%2]'
with
T0.[Refdate] >= ''[%1]'' AND
T0.[Refdate] <= ''[%2]''
(I also added a space before the AND in the first of these two lines while I was editing your question.)