Extract some digits after word id - postgresql

I have a table with a Name column and a Log column.
Name Log
Michelle Bad 222 news travels id 54585 fast.
Lucy Barking 333 dogs id 545584 seldom bite.
Green Beauty is 444 in the id 85955 eyes of the beholder.
Gail Beggars 123 can't be ID 4658 choosers.
I want to extract only the ID digits from log column. Note that the word ID could be capitalized or not. Hence, the output should be like this:
Name ID
Michelle 54585
Lucy 545584
Green 85955
Gail 4658
I tried to use the following query:
select name
, substring(log from E'^(.*?)[id< ]') as id
from mytable;
However, I cannot have the output I need.

Something along these lines should work. Since you didn't provide CREATE TABLE and INSERT statements, I just used one row in a common table expression.
with data as (
select 'Michelle' as name, 'Bad 333 id 54342 wibble' as log
)
select name, substring(substring(log::text, '((id|ID) [0-9]+)'), '[0-9]+')
from data
where log::text ~* 'id [0-9]+';
The nested substring() calls first return the id number along with the string 'id', then return just the id number.

Related

String match in Postgresql

I am trying to make separate columns in my query result for values stored in in a single column. It is a string field that contains a variety of similar values stored like this:
["john"] or ["john", "jane"] or ["john", "john smith', "jane"],etc... where each of the values in quotes is a distinct value. I cannot seem to isolate just ["john"] in a way that will return john and not john smith. The john smith value would be in a separate column. Essentially a column for each value in quotes. Note, I would like the results to not contain the quotes or the brackets.
I started with:
Select name
From namestbl
Where name like %["john"]%;
I think this is heading in the wrong direction. I think this should be in select instead of where.
Sorry about the format, I give up trying to figure out the completely useless error message when i try to save this with table markdown.
Your data examples represent valid JSON array syntax. So cast them to JSONB array and access individual elements by position (JSON arrays are zero based). The t CTE is a mimic of real data. In the illustration below the number of columns is limited to 6.
with t(s) as
(
values
('["john", "john smith", "jane"]'),
('["john", "jane"]'),
('["john"]')
)
select s::jsonb->>0 name1, s::jsonb->>1 name2, s::jsonb->>2 name3,
s::jsonb->>3 name4, s::jsonb->>4 name5, s::jsonb->>5 name6
from t;
Here is the result.
name1
name2
name3
name4
name5
name6
john
john smith
jane
john
jane
john

How to use ts_query with ANY(anyarray)

I currently have a query in PostgreSQL like:
SELECT
name
FROM
ingredients
WHERE
name = ANY({"string value",tomato,other})
My ingredients table is simply a list of names:
name
----------
jalapeno
tomatoes
avocados
lime
My issue is that plural values in the array will not match single values in the query. To solve this, I created a tsvector column on the table:
name | tokens
---------------+--------------
jalapeno | 'jalapeno':1
tomatoes | 'tomato':1
avocados | 'avocado':1
lime | 'lime':1
I'm able to correctly query single values from the table like this:
SELECT
name,
ts_rank_cd(tokens, plainto_tsquery('tomato'), 16) AS rank
FROM
ingredients
WHERE
tokens ## plainto_tsquery('tomato')
ORDER BY
rank DESC;
However, I need to query values from the entire array. The array is generated from another function, so I have control over the type of each of items in the array.
How can I use the ## operand with ANY(anyarray)?
That should be straight forward:
WHERE tokens ## ANY
(ARRAY[
plainto_tsquery('tomato'),
plainto_tsquery('celery'),
plainto_tsquery('vodka')
])

Return only capitalised names from a SQL query

I have a table storing first names and surnames; some may be stored with capitalisation. Is there a query I could use to return only those rows with capitalisation?
For instance, if I have the following entries:
firstname | surname
-----------+-----------
Bob | Jones
john | bobbins
I'd only expect to be returned the record for "Bob Jones".
I'm sure it's not a difficult thing to do, but I haven't been able to find any examples anywhere.
Compare the value with the value where the first character is upper-case:
select *
from the_table
where firstname = initcap(firstname)
and surname = initcap(surname);
The function initcap() converts the first letter of each word to upper case and the rest to lower case.

SQl Server 2012 autofill one column from another

I have a table where a user inputs name, dob, etc. and I have a User_Name column that I want automatically populated from other columns.
For example input is: Name - John Doe, DOB - 01/01/1900
I want the User_Name column to be automatically populated with johndoe01011900 (I already have the algorithm to concatenate the column parts to achieve the desired result)
I just need to know how (SQL, Trigger) to have the User_Name column filled once the user completes imputing ALL target columns. What if the user skips around and does not input the data in order? Of course the columns that are needed are (not null).
This should do it:
you can use a calculated field with the following calculation:
LOWER(REPLACE(Name, ' ', ''))+CONVERT( VARCHAR(10), DateOfBirth, 112))
In the below sample I have used a temp table but this is the same for regular tables as well.
SAMPLE:
CREATE TABLE #temp(Name VARCHAR(100)
, DateOfBirth DATE
, CalcField AS LOWER(REPLACE(Name, ' ', ''))+CONVERT( VARCHAR(10), DateOfBirth, 112));
INSERT INTO #temp(Name
, DateOfBirth)
VALUES
('John Doe'
, '01/01/1900');
SELECT *
FROM #temp;
RESULT:

getting categoryid fo more than one shortname passed

I have the following tables:
business
id catid subcatid
---------------------
10 {1} {10,20}
20 {2} {30,40}
30 {3} {50,60,70}
cat_subcat
catid shortname parent_id bid
--------------------------------------------
1 A 10
2 B 20
3 c 30
10 x 1 10
20 y 1 10
30 z 2 20
40 w 2 20
Both the tables have a relationship using id. The problem I am getting is outlined below. Here is my query currently:
SELECT ARRAY[category_id]::int[] from cat_subcat
where parentcategoryid IS not NULL and shortname ilike ('x,y');
I want to get the category_id for an entered shortname, but my query is not giving the proper output. If I pass one shortname it will retrieve the category_id, but if I pass more than one shortname it will not display category_id. Please tell me how to get the category_id for more than one shortname passed.
To actually use pattern matching with ILIKE, you cannot use a simple IN expression. Instead, you need ILIKE ANY (...) or ALL (...), depending on whether you want the tests ORed or ANDed:
Also, your ARRAY constructor will be applied to individual rows, which seems rather pointless. I assume you want this instead (educated guess):
SELECT array_agg(catid) AS cats
FROM cat_subcat
WHERE parent_id IS NOT NULL
AND shortname ILIKE ANY ('{x,y}');
Well, as long as you don't use wildcards (%, _) for your pattern, you can translate this to:
AND lower(shortname) IN ('x','y');
But that would be rather pointless, since Postgres internally converts this to:
AND lower(shortname) = ANY ('{x,y}');
.. before evaluating.