Redshift - Pulling the right most value from cell - sql

I have a columns with list of fruit names. I am trying to extract the right most value from the cell. Cell can have one value or n values. In which case, I am expecting to pull the last value.
Given below sample shows the actual value (col name: name_of_fruits) and the expected value (col name: expected_value )
name_of_fruits, expected_value
apples|oranges, oranges
apples|bananas, bananas
apples, apples
apples|mango|pears, pears
I tried performing the below code:
select name_of_fruits, right((name_of_fruits),position('|' in reverse(name_of_fruits))-1) as expected_value from table
I get an error SQL Error Invalid operation : Invalid length (context : Negative value given)
Could anyone assist to pull the required values. Thanks
I am using Redshift DB.

Try using REGEXP_REPLACE:
SELECT
name_of_fruits,
REGEXP_REPLACE(name_of_fruits, '.*|', '') AS expected_value
FROM yourTable;
The pattern .*| works nicely here, because in the case of a name string which does have more than one fruit, it would strip everything off leaving only the final fruit. And, in the case of a name string having only one name, the replacement would just no-op, also leaving the same fruit name.

Related

How to retrieve the required string in SQL having a variable length parameter

Here is my problem statement:
I have single column table having the data like as :
ROW-1>> 7302-2210177000-XXXX-XXXXXX-XXX-XXXXXXXXXX-XXXXXX-XXXXXX-U-XXXXXXXXX-XXXXXX
ROW-2>> 0311-1130101-XXXX-000000-XXX-XXXXXXXXXX-XXXXXX-XXXXXX-X-XXXXXXXXX-WIPXXX
Here i want to separate these values from '-' and load into a new table. There are 11 segments in this string separated by '-', therefore, 11 columns. The problem is:
A. The length of these values are changing, however, i have to keep it as the length of these values in the standard format or the length which it has
e.g 7302- (should have four values, if the value less then that then keep that value eg. 73 then it should populate 73.
Therefore, i have to separate as well as mentation the integrity. The code which i am writing is :
select
SUBSTR(PROFILE_ID,1,(case when length(instr(PROFILE_ID,'-')<>4) THEN (instr(PROFILE_ID,'-') else SUBSTR(PROFILE_ID,1,4) end)
)AS [RQUIRED_COLUMN_NAME]
from [TABLE_NAME];
getting right parenthesis error
Please help.
I used the regex_substr SQL function to solve the above issue. Here below is an example:
select regex_substr('7302-2210177000-XXXX-XXXXXX-XXX-XXXXXXXXXX-XXXXXX-XXXXXX-U-XXXXXXXXX-XXXXXX ROW-2>> 0311-1130101-XXXX-000000-XXX-XXXXXXXXXX-XXXXXX-XXXXXX-X-XXXXXXXXX-WIPXXX',[^-]+,1,1);
Output is: 7302 --which is the 1st segment of the string
Similarly, the send string segment which is separated by "-" in the string can be obtained by just replacing the 1 with 2 in the above query at the end.
Example : select regex_substr('7302-2210177000-XXXX-XXXXXX-XXX-XXXXXXXXXX-XXXXXX-XXXXXX-U-XXXXXXXXX-XXXXXX ROW-2>> 0311-1130101-XXXX-000000-XXX-XXXXXXXXXX-XXXXXX-XXXXXX-X-XXXXXXXXX-WIPXXX',[^-]+,1,2);
output: 2210177000 which is the 2nd segment of the string

sql server logic to workout the right most position of the numeric field will have a sign OVER it designating positive or negative

Example of the data in csv
Column_header
000000025000{
000000007185E
The doucmention I have
*The right most position of the numeric field will have a sign OVER it
designating positive or negative.
Example of Data
I dont understand how write the logic to support the the symbol,number,letter to get the correct value.
I'd create a table (or view) with the static mapping of character-value, meaning:
Symbol
Value
J
-1
A
+1
about the data rows themselves, it seems to me there is always a symbol at the end, therefore you can split the data into two columns, value, and symbol...
I have no idea about how the data are inserted but it seems logically easy
SELECT
_YourValue_
,LEFT(_YourValue_, LENGTH(_YourValue_)-1) as Value
,RIGHT(_YourValue_, 1) as Symbol
FROM _Whatever_
you can also cast to whatever datatype is correct for those data.
Finally you can join the tables and show/calculate whatever is needed
select value , if(value LIKE '%{%' or value LIKE '%J%' or value LIKE '%E%' or value LIKE '%C%',concat(SUBSTRING(value,1,char_length(value)-1),'+'),concat(SUBSTRING(value,1,char_length(value)-1),'-')) as new_value from yourtablename
Output
value
New Value
000000025000{
000000025000+
000000007185E
000000007185+
Add all other character on first parameter of if clause for positive designation.

Creating a column containing only a specific value of another column

I have table such as
column
abcx sample 6.5oz
bbcd sku 2ct
tty 80z
rre pool 65g box
How can I create a new column in my select statement that would just give me what the size of each row value is? ( 6.50z, 2ct, 80z, 65g)
desired output:
size
6.5oz
2ct
90z
65g
The question is not specified precisely.
Here's a solution assuming you're interested in "a sequence of digits, possibly containing a dot, immediately followed by a sequence of lowercase letters".
If so, this should do it:
select col, regexp_substr(col, '[\\d\\.]+[a-z]+') from test;
If this is not what you're looking for, please make the question very specific

SQL Server: How to select rows which contain value comprising of only one digit

I am trying to write a SQL query that only returns rows where a specific column (let's say 'amount' column) contains numbers comprising of only one digit, e.g. only '1's (1111111...) or only '2's (2222222...), etc.
In addition, 'amount' column contains numbers with decimal points as well and these kind of values should also be returned, e.g. 1111.11, 2222.22, etc
If you want to make the query generic that you don't have to specify each possible digit you could change the where to the following:
WHERE LEN(REPLACE(REPLACE(amount,LEFT(amount,1),''),'.','') = 0
This will always use the first digit as comparison for the rest of the string
If you are using SQL Server, then you can try this script:
SELECT *
FROM (
SELECT CAST(amount AS VARCHAR(30)) AS amount
FROM TableName
)t
WHERE LEN(REPLACE(REPLACE(amount,'1',''),'.','') = 0 OR
LEN(REPLACE(REPLACE(amount,'2',''),'.','') = 0
I tried like this in place of 1111111 replace with column name:
Select replace(Str(1111111, 12, 2),0,left(11111,1))

Problem with MySQL Select query with "IN" condition

I found a weird problem with MySQL select statement having "IN" in where clause:
I am trying this query:
SELECT ads.*
FROM advertisement_urls ads
WHERE ad_pool_id = 5
AND status = 1
AND ads.id = 23
AND 3 NOT IN (hide_from_publishers)
ORDER BY rank desc
In above SQL hide_from_publishers is a column of advertisement_urls table, with values as comma separated integers, e.g. 4,2 or 2,7,3 etc.
As a result, if hide_from_publishers contains same above two values, it should return only record for "4,2" but it returns both records
Now, if I change the value of hide_for_columns for second set to 3,2,7 and run the query again, it will return single record which is correct output.
Instead of hide_from_publishers if I use direct values there, i.e. (2,7,3) it does recognize and returns single record.
Any thoughts about this strange problem or am I doing something wrong?
There is a difference between the tuple (1, 2, 3) and the string "1, 2, 3". The former is three values, the latter is a single string value that just happens to look like three values to human eyes. As far as the DBMS is concerned, it's still a single value.
If you want more than one value associated with a record, you shouldn't be storing it as a comma-separated value within a single field, you should store it in another table and join it. That way the data remains structured and you can use it as part of a query.
You need to treat the comma-delimited hide_from_publishers column as a string. You can use the LOCATE function to determine if your value exists in the string.
Note that I've added leading and trailing commas to both strings so that a search for "3" doesn't accidentally match "13".
select ads.*
from advertisement_urls ads
where ad_pool_id = 5
and status = 1
and ads.id = 23
and locate(',3,', ','+hide_from_publishers+',') = 0
order by rank desc
You need to split the string of values into separate values. See this SO question...
Can Mysql Split a column?
As well as the supplied example...
http://blog.fedecarg.com/2009/02/22/mysql-split-string-function/
Here is another SO question:
MySQL query finding values in a comma separated string
And the suggested solution:
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set