How do I get the first match from regexp_match? - postgresql-13

I'd like to update a column with just the domain part of an email address.
update
users
set
email_base_domain = regexp_match(email, '(\w+\.\w+)$')
However, regexp_match returns a text[]. If email is example#foo.com the above sets email_base_domain to {foo.com}. I would like foo.com.
How do I get just the first element as text from the text[] returned by regexp_match?

Add a set of parentheses to group what you want to extract. For example:
SELECT regexp_matches(email, '(\w+)\.\w+$')
FROM users
will return {foo}, while
SELECT regexp_matches(email, '\w+\.(\w+)$')
FROM users
will return '{com}'.
Once you have a text array you can use regular array indexing to extract values from the returned text array. For example:
SELECT (regexp_matches(email, '(\w+)\.\w+$'))[1]
FROM users
returns 'foo' and
SELECT (regexp_matches(email, '\w+\.(\w+)$'))[1]
FROM users
returns 'com'.
db<>fiddle with other alternatives here

Related

How to update the SQL Server table based on different column value

I would like to update table called people from:
to
Could you please help?
You need to parse out the beginning of the email address to add it to the domain name. Do that by finding the CHARINDEX of the # symbol, then subtracting one. Use that value as the length parameter in a LEFT function call.
Once you have the name from the email address, CONCATenate it to the static value of your domainname\.
I included a WHERE clause that you may want to use if you have a large number of rows where the Username is already correct and you don't want to waste a bunch of writes replacing a string with a duplicate of that same string. You could leave the WHERE off if you prefer.
UPDATE People
SET Username = CONCAT('domainname\',LEFT([E-mailAddress],CHARINDEX('#',[E-mailAddress])-1))
WHERE
Username <> CONCAT('domainname\',LEFT([E-mailAddress],CHARINDEX('#',[E-mailAddress])-1));
If you are working on earlier versions (cause CONCAT() is for 2012+ versions) and also if you have NULLs in the UserName column, you can do like
CREATE TABLE T(
[E-MailAddress] VARCHAR(50),
UserName VARCHAR(45)
);
INSERT INTO T VALUES
('abc#domainname.com', 'abc'),
('zxc#fhlbdm.com', NULL),
('MNO#domainname.com', 'MNO'),
('pqr#domainname.com', 'pq'),
('tyu#domainname.com', 'domainname\tyu');
UPDATE T
SET UserName = 'domainname\' + LEFT([E-MailAddress], CHARINDEX('#', [E-MailAddress])-1)
WHERE 'domainname\' + LEFT([E-MailAddress] , CHARINDEX('#', [E-MailAddress])-1) <> UserName
OR
UserName IS NULL;
SELECT *
FROM T;

SQL Server - add to this query to first check for existence of a string

I have an nvarchar field in my database called CatCustom which contains comma-separated 5-character codes. It can contain as little as one code, or as many as 20 codes, separated by commas.
Right now, I use this query to add a new 5-character code to the field in given records (in this case the new code is LRR01):
UPDATE dbo.Sources
SET CatCustom = CONCAT_WS(', ', RTRIM(CatCustom), 'LRR01')
WHERE SourceID IN (1,2,3,4,5,8,9,44,63,45,101,102,222,344)
I need to add to this though: I need the record to be updated only if that 5-character code doesn't already exist somewhere in the CatCustom field, to ensure that code is not in there more than once.
How would I accomplish this?
EDIT: I really don't understand how this can be considered a duplicate of the suggested thread. This is a VERY specific case and has nothing to do with creating stored procedures and or variables. The alleged duplicated thread does not really help me - sorry.
Use STRING_SPLIT function to split the comma separated list and then add Not Exist condition in the WHERE clause like below
UPDATE dbo.Sources
SET CatCustom = CONCAT_WS(', ', RTRIM(CatCustom), 'LRR01')
WHERE SourceID IN (1,2,3,4,5,8,9,44,63,45,101,102,222,344)
AND NOT EXISTS (SELECT 1 FROM STRING_SPLIT(CatCustom, ',') where value = 'LRR01')
UPDATE dbo.Sources
SET
CatCustom = CONCAT_WS(', ', RTRIM(CatCustom), 'LRR01')
WHERE
SourceID IN (1,2,3,4,5,8,9,44,63,45,101,102,222,344)
AND CatCustom NOT LIKE '%LRR01%';

SQL XML parsing using a attribute value supplied by another field in the same row

Context: I'm scraping some XML form descriptions from a Web Services table in hopes of using that name to identify what the user has inputted as response. Since this description changes for each step (row) of the process and each product I want something that can evaluate dynamically.
What I tried: The following was quite useful but it returns a dynamic attribute query result in it's own field ans using a coalesce to reduce the results as one field would lead to it's own complications: Get values from XML tags with dynamically specified data fields
Current Attempt:
I'm using the following code to generate the attribute name that I will use in the next step to query the attribute's value:
case when left([Return], 5) = '<?xml'
then lower(cast([Return] as xml).value('(/response/form/*/#name)[1]','varchar(30)'))
else ''
end as [FormRequest]
And as part of step 2 I have used the STUFF function to try and make the row-level query possible
case when len(FormRequest)>0
then stuff( ',' + 'cast([tmpFormResponse] as xml).value(''(/wrapper/#' + [FormRequest] + ')[1]'',''varchar(max)'')', 1, 1, '')
else ''
end as [FormResponse]
Instead of seeing 1 returned as my FormReponse feild value for the submit attribute (please see in yellow below) it's returning the query text -- cast([tmpFormResponse] as xml).value('(/wrapper/#submit)1','varchar(max)') -- instead (that which should be queried).
How should I action the value method so that I can dynamically strip out the response per row of XML data in tmpFormResponse based on the field value in the FormRequest field?
Thanx
You can check this out:
DECLARE #xml XML=
N'<root>
<SomeAttributes a="a" b="b" c="c"/>
<SomeAttributes a="aa" b="bb" c="cc"/>
</root>';
DECLARE #localName NVARCHAR(100)='b';
SELECT sa.value(N'(./#*[local-name()=sql:variable("#localName")])[1]','nvarchar(max)')
FROM #xml.nodes(N'/root/SomeAttributes') AS A(sa)
Ended up hacking up a solution to the problem by using PATINDEX and CHARINDEX to look for the value in the [FormRequest] field in the he tmpFormResponse field.

SSRS Blank Parameters

I have 3 simple parameters, all which are text, and allow for multiple values as well as blank values. There are no available values or default values, as I want the users to type the value themselves. When leaving all parameters blank, no data is shown, because there are no blank values. However, I want to show all data when there is no value entered for the parameter. How can I do this?
This is what the query looks like right now
SELECT [PROGRAMNO]
,[ACCTNO]
,[CLAIMNO]
,[TOTALCHARGES]
,[TOTALPAYMENT]
,[TYPE]
FROM DATALINE
WHERE PROGRAMNO IN (#PROGRAMNO)
AND ACCTNO IN (#ACCTNO)
AND CLAIMNO IN (#CLAIMNO)
You can add an OR to allow for the NULL (or blank) value for each condition - depending on which you have allowed in the parameter.
WHERE (PROGRAMNO IN (#PROGRAMNO) OR #PROGRAMNO is null)
AND (ACCTNO IN (#ACCTNO) OR #ACCTNO IS NULL)
AND (CLAIMNO IN (#CLAIMNO) OR #CLAIMNO IS NULL)
or if you allow blank values instead:
WHERE (PROGRAMNO IN (#PROGRAMNO) OR #PROGRAMNO = '' )
AND (ACCTNO IN (#ACCTNO) OR #ACCTNO = '' )
AND (CLAIMNO IN (#CLAIMNO) OR #CLAIMNO = '' )
Multi-value parameters do not allow blank input. So you will need to add an item to your dropdown list that represents the blank value. If you are manually specifying the available values you would simply add this to the list. The value would be blank and the label could be something like "Blank" or "N/A". If you are using a query to populate the available values you will need to UNION this blank value to the other results. Either way, you'll also need to account for this in your WHERE clause in the main dataset as Hannover Fist pointed out.

How do I return one element from string_to_array() in PostgreSQL 8.4?

I want to parse a field with the following type of value:
"DAVE EBERT CONSTRUCTION~139 LENNOX STREET~SANTA CRUZ, CA 95060~~Business Phone Number:(831) 818-3170"
I would like to do a query like:
Update mytable set street = string_to_array(myfield,'~')[2]
But string_to_array does not "return" an array so it can't be chained in this way. However, it does return an array that can be used by other functions that take arrays like array_upper() so I don't know why it would not work.
My workaround is to create an array field and do this:
Update mytable set myfield_array = string_to_array(myfield,'~')
Update mytable set street = myfield_array[2]
Is there a more direct way to do this? But again, if I am extracting a lot of different array elements, maybe the less direct way performs better because you are converting string to array only once?
Try...
Update mytable set street = (string_to_array(myfield,'~'))[2]
You just need those parenthesis.
Use some extra ():
Update mytable set street = (string_to_array(myfield,'~'))[2]

Resources