I have the below query.
SQLFiddle
I can only have possible 7 characters (- and A-Z combined)
There can only be ONE "-" for first 5 characters (Monday to Friday)
For Saturday and Sunday, we can only have one character or dash
I am replacing Sa and Su with just S
However, whenever they are passing in TWO dashes for Saturday AND/OR Sunday, I need to replace them with ONE dash for each
so length can only be 7 after all manipulations.
I have tried w/e I could but getting stuck at the two vs one dash scenario for Saturday/Sunday position.
Please help! I will keep this updated as I find more.
THX in ADV
Code:
CREATE Table TempTable (string varchar(50))
INSERT INTO TempTable (string)
VALUES ('MTWRFSS')
,('MTWRFSaS')
,('MTWRFSaSu')
,('----F--')
,('----F----')
,('MT------')
,('MT------')
,('----FSa--')
,('----FSa-')
,('----FS--')
,('----FS-')
,('----F-Su')
,('----F--Su')
,('----F-S')
,('----F--S')
UPDATE TempTable
SET string = REPLACE(REPLACE(RTRIM(LTRIM(string)),'SA','S'),'SU','S')
SELECT string
,LEN(String) AS stringLengh FROM TempTable
--DROP TABLE TempTable
Try to manipulate only characters after 5th, because from MON to FRY you always have 1 -.
So I think this will work:
SELECT
string as InitialString
,LEFT(LEFT(String,5) + replace(replace(replace(RIGHT(String,LEN(String)-5),
'Sa','S'),'Su','S'),'--','-') + '--',7) as FinalString
FROM TempTable;
You have to cut string into 2: left 5 and the rest. Then using several replaces you can have correct Sat/Sun combination. Concatenate both and you will have final decision.
Also 2 more dashes have to be added and the you have to take only LEFT 7, because if you have '--' it will be replaced with '-'.
Related
I have several columns where I have to replace positions in strings with underscores.
i.e.
11 11_modified
XX4RDGCG9DR XX4RDGCG__R
12 12_modified
XX4RDGCG9DRX XX4RDGCG___X
13 13_modified
XX4RDGCG9DRXY XX4RDGCG____Y
Notice that I will always just need the first 8-digits, but depending on the column, the number of underscores changes and I only need the last value of a string-value.
11... has 2 underscores at the 9th and 10th position, 12... has 3 underscores at the 9th, 10th, and 11th position, and 13 has 4 underscores at the 9th, 10th, llth, and 12th position.
How would I do this?
Using CONCAT and string manipulation functions:
SELECT col,
CONCAT(LEFT(col, 8), REPEAT('_', LEN(col)-9), RIGHT(col, 1)) AS modified
FROM tab;
For sample input:
CREATE OR REPLACE TABLE tab
AS
SELECT 'XX4RDGCG9DR' AS col UNION
SELECT 'XX4RDGCG9DRX' UNION
SELECT 'XX4RDGCG9DRXY';
Output:
Another alternative using insert
insert( <base_expr>, <pos>, <len>, <insert_expr> )
set str='XX4RDGCG9DRX';
select insert($str,9,len($str)-9,repeat('_',len($str)-9));
Update:
I noticed both Lukasz's and my solution return unexpected result if len($str) < 9. To fix for that, modify that to the following so that strings that don't qualify remain unchanged. I would honestly use a where clause or a case expression instead
set str='XG9DR';
select insert($str,9,greatest(len($str)-9,0),repeat('_',len($str)-9));
When I execute the script (whithout comments and replacing the "." by spaces):
SET SQLBLANKLINES ON
UPDATE ANY_TABLE SET VARCHAR2_COLUMN='Hello
..... -- 1st empty line with trailing spaces
Kitty
...' -- last empty line with trailing spaces
WHERE ID='something';
it is saved in the database like:
'Hello
-- 1st empty line WITHOUT spaces
Kitty
...' -- last empty line WITH trailing spaces
So the spaces in the 1st blankline are lost but not on the last one. And I am using "SET SQLBLANKLINES ON" !!
Can anybody explain me what I'm doing wrong? Or What misconception I have?
The problem is the same with an insert and is independent of using simple spaces or tabs.
In fact, thanks to Alex Pool, we can simplify the example:
Why are the next queries returning different value lengths?
select length('Hello
...... --6 characters (spaces)
Kitty') from dual;
-- returns 12
select length('Hello
x..... -- 6 characters (an 'x' + 5 spaces)
Kitty') from dual;
-- returns 18
select length('Hello
'||'......
Kitty') from dual;
-- returns 18
What I am using:
SQLDeveloper 20.2.0.175
Oracle database 19
The problem may be related to this other one
The q'[]' function is your friend.
create table multiline_strings
(id integer,
words varchar2(256));
insert into multiline_strings (id, words) values
(
1,
q'[Hello
Kitty
]');
See this question/answer - probably should close this as a duplicate.
I have file ids in my database that start with:
a single character prefix
a period
a three digit client id
a hyphen
a three digit file number.
Example F.129-123
We have several ids for each client.
I need to be able to strip out the three digit file number and then pull them based on even or odd so that I can assign specific data to each result population.
One added issue. Some of the ids have characters added at the end.
Example: F.129-123A or F.129-123.NF
So I need to be able to just use the three digit file number without any other characters, because the added characters create errors while conversion.
If you are using SQL SERVER,
you can use CHARINDEX() to find the index of - and then
get 3 digits after - using SUBSTRING()
SELECT substring('F.123-234',charindex('-','F.123-234')+1, 3)
If you are using MySQL,
you can use POSITION() to find the index of - and then get 3 digits after - using SUBSTRING()
SELECT SUBSTRING('F.123-234',POSITION( '-' IN 'F.123-234' )+1,3);
If you are using Oracle,
you can use INSTR() to find the index of - and then get 3 digits after - using SUBSTR()
UPDATES:
Based on the requirements in comments, you can use a query like below achieve what you need.
SELECT
SUBSTRING(MatterID,CHARINDEX('-',MatterID)+1, 3) as FileNo
FROM
Matters
WHERE
MatterID LIKE'f.129%'
AND MatterID NOT LIKE '%col%'
AND substring( MatterID, CHARINDEX('-',MatterID)+1, 3) % 2 = 0
If you are working with Microsoft SQL Server, then you could use of patindex() function with substring() function to get the only 3 digits file number
select left(substring(string, PATINDEX('%[0-9][-]%', string)+2, LEN(string)), 3)
Note that if you have other period (i.e. -, /) then you will need to modify chars like PATINDEX('%[0-9][/]%')
In Postgres you can use split_part() to get the part after the hyphen, then cast it to an integer:
select *
from the_table
order by split_part(file_id, '-', 2)::int;
This assumes that there is always exactly one - in the string. I understand your question that this is the case as the format is fixed.
Is this helpful
Create table #tmpFileNames(id int, FileName VARCHAR(50))
insert into #tmpFileNames values(1,'F.129-123')
insert into #tmpFileNames values(2,'F.129-125')
insert into #tmpFileNames values(3,'F.129-124')
insert into #tmpFileNames values(4,'F.129-123A')
insert into #tmpFileNames values(5,'F.129-124B')
insert into #tmpFileNames values(6,'F.129-125.PQ')
insert into #tmpFileNames values(7,'F.129-123.NF')
select SUBSTRING(STUFF(FileName, 1, CHARINDEX('-',FileName), ''),0,4), * from #tmpFileNames
Order by SUBSTRING(STUFF(FileName, 1, CHARINDEX('-',FileName), ''),0,4),id
Drop table #tmpFileNames
I'm trying to substring the last 3 digits from a column. Problem is, some of them have a random space at the end, which then only returns 2 of the 3 needed values from the column. Right now I have:
SELECT substr(infovalue, -3)
FROM TABLE
WHERE INFOCODE = 555
How can I get my statement to ignore the space at the end?
thanks!
I guess you are in Oracle. Apply an rtrim to remove all trailing spaces
SELECT substr(rtrim(infovalue), -3)
FROM TABLE
WHERE INFOCODE = 555
And please specify the vendor & product version for all your questions.
I am using SQL Server 2005 and I want to extract the alpha part of a string.
i.e.
From ABC123, I would like to get ABC
From AB1234, I would like to get AB.
etc etc.
What is the easiest way to do this?
Always letters then digits i.e. XYZ123 or XZ321 etc – GordyII Mar 2
'10 at 0:26
I know this is an old post BUT... If the quote above is true, then this is easy...
SELECT LEFT(YourStringColumn, PATINDEX('%[0-9]%',YourStringColumn)-1)
FROM dbo.YourTable
You could make a user defined function that would loop through the characters and build up a new string where the characters were letters.
if there is always a space between the letter and the digits, try:
DECLARE #String varchar(100)
SET #String='ABC 123'
SELECT LEFT(#String,LEN(#String)-CHARINDEX(' ',#String))
OUTPUT
-------------------
ABC
(1 row(s) affected)
EDIT after OP's comment, assumes no space before digits:
DECLARE #String varchar(100)
SET #String='ABCD123'
;with Numbers AS
(
SELECT 1 AS Number,ISNUMERIC(SUBSTRING(#String,1,1)) AS Digit
UNION ALL
SELECT Number+1,ISNUMERIC(SUBSTRING(#String,Number+1,1)) AS Digit
FROM Numbers
WHERE Number<LEN(#String)
)
SELECT LEFT(#String,MAX(Number)) FROM Numbers WHERE Digit=0
--OPTION (MAXRECURSION n) --if the string is longer than 100 characters uncomment this and set "n" to the string length
OUTPUT:
-------------------
ABCD
(1 row(s) affected)
You also might consider doing this not in SQL but somewhere else, if it is possible in your scenario. If you explain what kind of data are you working with how they get into your sql database and what and how uses them it might be possible to suggest a better alternative.