I am trying to delete the "-" and everything to the left of the "-" in the following example:
Adams Mark - 1234 Main St, Anyville VA, 12345
In T-SQL this would work;
declare #foo varchar(60) = 'Adams Mark - 1234 Main St, Anyville VA, 12345'
select substring(#foo,charindex('-',#foo,1)+1,len(#foo)-charindex('-',#foo,1) )
I took you quite literally and left the leading space.
Try this:
SELECT SUBSTRING(colName, CHARINDEX(colName, '-') + 1, LEN(colName))
FROM table1;
sqlfiddle demo
I guess you can do something like this .... I dont really know what you mean when you say you want to delete I guess you are trying to Update a column anyway the following will extract the desired string of you actual data.
Declare #Var VARCHAR(100) = 'Adams Mark - 1234 Main St, Anyville VA, 12345'
SELECT RIGHT(#Var, LEN(#Var)- CHARINDEX('-', #Var))
Result String
1234 Main St, Anyville VA, 12345
Edit
SELECT RIGHT(Column_Name, LEN(Column_Name)- CHARINDEX('-', Column_Name))
FROM Table_Name
PHP
$string = explode("-","Adams Mark - 1234 Main St, Anyville VA, 12345");
$string = trim($string[0]);
JS
var s = "Adams Mark - 1234 Main St, Anyville VA, 12345";
s = s.substring(0, s.indexOf('-'));
Related
I have an issue where I'm trying to remove all of the '.' from the string/filename below in SSMS apart from the last one which dictates file type.
EPC 14.10.14.pdf
Ideally I would like this string to appear as below:
EPC 141014.pdf
Any help would be appreciated
As a variable :
declare #doc varchar(30) = 'EPC 14.10.14.pdf'
declare #ext varchar(8) = right(#doc, charindex('.', reverse(#doc)));
set #doc = concat(replace(left(#doc,len(#doc)-len(#ext)),'.',''), #ext);
select #doc as doc;
doc
EPC 141014.pdf
As a table column :
create table test (
doc varchar(30) not null
);
insert into test (doc) values
('EPC 14.10.14.pdf'),
('FQD 15.11.15.jpeg');
select doc
, undotted_doc = concat(replace(left(doc, len(doc)-charindex('.', reverse(doc))),'.',''), right(doc, charindex('.', reverse(doc))))
from test;
doc
undotted_doc
EPC 14.10.14.pdf
EPC 141014.pdf
FQD 15.11.15.jpeg
FQD 151115.jpeg
Test on db<>fiddle here
Use replace,substring and len function
select replace(substring(#x,0,len(#x) - 3),'.','') + substring(#x,len(#x) - 3,len(#x))
EDIT:
If the name extension has a variable length, you can use the following query
select
CONCAT(
replace(substring(#x,0,len(#x) - CHARINDEX('.',TRIM(REVERSE(#x)))),'.','')
,
substring(#x,len(#x) - CHARINDEX('.',TRIM(REVERSE(#x))),len(#x))
)
Result
If you have extensions with different length (e.g. docx, xls), you need to find the index of the last occurrence of the . character using REVERSE() and CHARINDEX():
SELECT CONCAT(
REPLACE(SUBSTRING(SomeText, 1, LEN(SomeText) - CHARINDEX('.', REVERSE(SomeText))), '.', ''),
STUFF(SomeText, 1, LEN(SomeText) - CHARINDEX('.', REVERSE(SomeText)), '')
) AS FileName
FROM (VALUES
('EPC 14.10.14.pdf'),
('EPC 14.10.14.docx'),
('14.10.14.xlsx')
) t (SomeText)
Result:
FileName
----------------
EPC 141014.pdf
EPC 141014.docx
141014.xlsx
One more way.
SQL
SELECT fileName AS [Before]
, CONCAT(CONCAT(PARSENAME(fileName,4), PARSENAME(fileName,3), PARSENAME(fileName,2))
, '.', PARSENAME(fileName,1)) AS [After]
FROM (VALUES
('EPC 14.10.14.pdf'),
('EPC 14.10.14.docx'),
('14.10.14.xlsx'),
('csharp.10.14.cs')
) AS t(fileName);
Output
+-------------------+-----------------+
| Before | After |
+-------------------+-----------------+
| EPC 14.10.14.pdf | EPC 141014.pdf |
| EPC 14.10.14.docx | EPC 141014.docx |
| 14.10.14.xlsx | 141014.xlsx |
| csharp.10.14.cs | csharp1014.cs |
+-------------------+-----------------+
I have a table that has a column like the one below
url
----------------
dir=mp3\cat152AB&fileName=file-01.mp3
dir=mp3\cat2500DfDD00&fileName=file-02.mp3
dir=mp3\cat4500f0655&fileName=file-03.mp3
...
How can I delete extra strings and arrange the fields as follows in SQL Server.
url
----------------
file-01
file-02
file-03
...
you can use charindex and substring :
SELECT substring ('dir=mp3\cat152AB&fileName=file-01.mp3', CHARINDEX('fileName=', 'dir=mp3\cat152AB&fileName=file-01.mp3') +9 ,
LEN('dir=mp3\cat152AB&fileName=file-01.mp3')-CHARINDEX('fileName=', 'dir=mp3\cat152AB&fileName=file-01.mp3')
) AS MatchPosition;
CHARINDEX and SUBSTRING can help you, please check the example:
select substring (field, charindex (';fileName=', field) + len (';fileName='), len (field) - len ('.mp3') + 1 - charindex (';fileName=', field) - len (';fileName='))
from (
select 'dir=mp3\cat152AB&fileName=file-01.mp3' field union all
select 'dir=mp3\cat2500DfDD00&fileName=file-02.mp3' union all
select 'dir=mp3\cat4500f0655&fileName=file-03.mp3'
) a
The information you want always seems to be the 11th to 5th characters before the end of the string. I would suggest a simple solution:
select left(right(url, 11), 7)
Here is a db<>fiddle.
Please try the following method.
It is using tokenization via XML/XQuery.
SQL
-- DDL and sample data population, start
DECLARE #tbl TABLE (ID INT IDENTITY PRIMARY KEY, url VARCHAR(255));
INSERT INTO #tbl (url) VALUES
('dir=mp3\cat152AB&fileName=file-01.mp3'),
('dir=mp3\cat2500DfDD00&fileName=file-02.mp3'),
('dir=mp3\cat4500f0655&fileName=file-03.mp3');
-- DDL and sample data population, end
DECLARE #separator CHAR(1) = '=';
SELECT id, url
, LEFT(x, CHARINDEX('.', x) - 1) AS Result
FROM #tbl
CROSS APPLY (SELECT CAST('<root><r><![CDATA[' +
REPLACE(url, #separator, ']]></r><r><![CDATA[') +
']]></r></root>' AS XML)) AS t1(c)
CROSS APPLY (VALUES (c.value('(/root/r[last()]/text())[1]', 'VARCHAR(100)'))) AS t2(x);
Output
+----+------------------------------------------------+---------+
| id | url | Result |
+----+------------------------------------------------+---------+
| 1 | dir=mp3\cat152AB&fileName=file-01.mp3 | file-01 |
| 2 | dir=mp3\cat2500DfDD00&fileName=file-02.mp3 | file-02 |
| 3 | dir=mp3\cat4500f0655&fileName=file-03.mp3 | file-03 |
+----+------------------------------------------------+---------+
I know we have an accepted answer but I wanted to chime in with another simple, high-performing solution that addresses file names and file extensions with various lengths. For fun I included a parameter that allows you to include the file extension if you choose.
--==== Easily Consumable Sample Data
DECLARE #link TABLE ([url] VARCHAR(100) UNIQUE);
INSERT #link VALUES ('dir=mp3\cat152AB&fileName=file-01.mp3'),
('dir=mp3\cat2500DfDD00&fileName=file-02.mp3'),
('dir=mp3\cat4500f0655&fileName=file-03.mp3'),
('dir=mp3\cat4500f0655&fileName=file-999.mp3'),
('dir=mp3\cat4500d9997&fileName=file-0021.prodigi');
--==== Allows you to determine if you want the file extension
DECLARE #exclude BIT=1;
SELECT l.[url], TheFile = SUBSTRING(l.[url], s.Pos, s.Ln-s.Pos- ((#exclude*(fl.Ln)-1)))
FROM #link AS l
CROSS APPLY (VALUES(CHARINDEX('.',REVERSE(l.[url])))) AS fl(Ln)
CROSS APPLY (VALUES(CHARINDEX('fileName=',l.[url])+9, LEN(l.[url]))) AS s(Pos,Ln);
#exclude=1 returns:
url TheFile
----------------------------------------------------- --------------
dir=mp3\cat152AB&fileName=file-01.mp3 file-01
dir=mp3\cat2500DfDD00&fileName=file-02.mp3 file-02
dir=mp3\cat4500d9997&fileName=file-0021.prodigi file-0021
dir=mp3\cat4500f0655&fileName=file-03.mp3 file-03
dir=mp3\cat4500f0655&fileName=file-999.mp3 file-999
#exclude=0 returns:
url TheFile
----------------------------------------------------- --------------
dir=mp3\cat152AB&fileName=file-01.mp3 file-01.mp3
dir=mp3\cat2500DfDD00&fileName=file-02.mp3 file-02.mp3
dir=mp3\cat4500d9997&fileName=file-0021.prodigi file-0021.prodigi
dir=mp3\cat4500f0655&fileName=file-03.mp3 file-03.mp3
dir=mp3\cat4500f0655&fileName=file-999.mp3 file-999.mp3
is it possible, in postgresql - to access a cte defined in a view?
By that I mean - if you have the following:
create view my_view as
with
blah as (select 1 as x, 2 as y, 3 as z)
select
x*x as x_squared,
y*y as y_squared,
z*z as z_squared
from
blah
is there any way from outside of getting at blah? eg looking for something like:
select * from my_view.blah
Basically we have large views that use a number of complicated CTE's - and it's quite difficult sometimes to troubleshoot them without splitting them all out into separate smaller views [yes, I would prefer to just keep it like that, but I don't have that option]
I know I will be able to do it by making a stored proc that pulls out the view definition - extracts the with clauses, parses up to the blah definition, changes that to the main select, gets rid of the rest, and then does the query - but that all seems like a lot of work. Am hoping there's a built-in way?
You can create the CTE as a view by itself. For example:
create table a (b int);
insert into a (b) values (1), (50), (200), (350), (1000);
create view blah as
select * from a where b > 100;
Anf then base your original view on this new intermediate one to avoid repeating code:
create view my_view as
select * from blah where b < 500;
See running example at DB Fiddle.
ok - so I have a sort of solution - it's a not a function - it's a procedure that turns a cte into a materialized_view.
I first wanted to formulate it as function, so you could say:
select * from cte_from( 'my_real_view', 'the_cte' )
but it appears that a function needs its schema defined in advance, which is obviously impossible in this case. If anyone can suggest a hack to make it closer to above, I'd apperciate it. But anyway - bottom line this works:
create procedure from_cte(view_schema text, view_name text, cte_name text, materialized_view_name text) as
$func$
declare
_code text;
_others text;
_script text;
begin
execute format('drop materialized view if exists %s', materialized_view_name);
with recursive
string_provider as (
select view_definition as the_string,
position(concat(cte_name, ' as (') in lower(view_definition)) + length(cte_name) + 5 as start_location
from information_schema.views
where table_name = view_name
and table_schema = view_schema
),
string_walk as (
select start_location as x,
1 as brackets
from string_provider
union
select x + 1,
new_brackets
from string_provider,
string_walk,
lateral (select case
when substring(the_string from x + 1 for 1) = '(' then brackets + 1
when substring(the_string from x + 1 for 1) = ')' then brackets - 1
else brackets
end as new_brackets
) calculated
where new_brackets != 0
and x < length(the_string)
)
select substring(the_string from start_location for 1 + max(x) - start_location),
trim(substring(the_string from 0 for start_location - length(cte_name) - 5))
into _code, _others
from string_walk,
string_provider
group by the_string, start_location;
if length(_others) < 5 then
select _code into _script;
else
select concat(substring(_others from 0 for length(_others)), ' ', _script) into _script;
end if;
execute format('create materialized view %s as ( %s )', materialized_view_name, _code);
end
$func$ language plpgsql;
I have 2 questions here.
I have a column 'Campaign' with these entries. My objective is to extract the Cost part from the string and create a new column Cost in my table
29693214 - Live -JUTL Phase 2 Creator Stories Trailer * 7.12 - 7.25 * Video Views * $28,169.01 * BG - Mob
89695072 - Live -WUTL Retargeting JG * 7.16 - 7.31 * Link Clicks * $23,474.18 * KG - Mob
I tried select SUBSTRING(Campaign,CHARINDEX('$',Campaign) +1,???) .I am unable to figure out the '???' part. I want to start with the index next to '$' and continue till the '*' symbol to capture the cost.
While creating a new column I follow these steps
Alter table T ADD NewColumn varchar(100)
then I do this
Update T SET NewColumn = 'Say I want that cost part from the above question here'
Is there any efficient way to do this in single shot?
I think apply makes these operations a bit simpler:
select left(v1.str1, charindex(' ', v1.str1))
from (values ('29693214 - Live -JUTL Phase 2 Creator Stories Trailer * 7.12 - 7.25 * Video Views * $28,169.01 * BG - Mob')) v(str) cross apply
(values (stuff(str, 1, charindex('$', str), ''))) v1(str1);
This can readily be incorporated into an update:
Update t
set newcolumn = left(v.str1, charindex(' ', v.str1))
from t cross apply
(values (stuff(t.str, 1, charindex('$', str), ''))) v(str1)
DDL for testing query:
declare #tbl table(Campaign varchar(200));
insert into #tbl values
('29693214 - Live -JUTL Phase 2 Creator Stories Trailer * 7.12 - 7.25 * Video Views * $28,169.01 * BG - Mob'),
('189695072 - Live -WUTL Retargeting JG * 7.16 - 7.31 * Link Clicks * $23,474.18 * KG - Mob');
If the cost is always separated by a asterisk * from other part of the string, you could use below query:
select trim(substring(Campaign, dollarIndex + 1, asteriskIndex - dollarIndex - 1)) from (
select Campaign, charindex('$', Campaign) dollarIndex,
charindex('*', Campaign, charindex('$', Campaign)) asteriskIndex
from #tbl
) a
To use it in update statement, you could use the same query, but we need to transform above into single query:
update #tbl set Campaign = trim(substring(Campaign, charindex('$', Campaign) + 1, charindex('*', Campaign, charindex('$', Campaign)) - charindex('$', Campaign) - 1))
Note: consider if it's worthy keeping data that you already have (redundancy). If it can be always be parsed from your column in the same way you could use view for this task.
On the other hand it might be qiute expensive to query such data and might be bad for performance.
I'm using this code:
library(RODBC)
sql3 <- "SELECT TOP 10 Address AS Addr
FROM dbo.Address
Where CountryCode = 'RU'"
con <- odbcDriverConnect('driver={SQL SERVER};server=servername;database=databasename;trusted_connection=true')
df <- as.data.frame(sqlQuery(con,sql3),stringsASFactors=FALSE)
print(df)
Which produces the following results:
> print(df)
Addr
1 115573, ??????, ???????? ?-?, ?.22?
2 107113 ??????, ????? ???????????, ??? 26
3 142200 ??, ?.????????, ??????????? ?., ?. 1
4 614022 ?????, ?????????????? ?????, ??. ????, 37?
5 109453 ?. ?????? ????????????? ????????, ?. 19, ???. 2
6 129282 ??????, ??. ???????, ?.13-?
7 603000 ?????? ????????, ??????? ????????, 2
8 103164 ??????, ????? ??????? ???????????, ??? 26
9 197341, ?????-?????????, ??-? ???????????, ?.19, ????.2
10 429950, ?????????? ???????, ?. ??????????????, ??. ??????????, 42?
The results should be a list of Russian addresses.
As you can maybe see, all 'regular' characters are getting imported fine (e.g. numbers), but the Russian characters aren't making it. I'm guessing I somehow need to set the character encoding before it reaches the dataframe, but I'm not sure how to do that. Also to clarify, the correct address characters appear when the data is queried from SSMS.
Any pointers would be appreciated, thanks.
The ? will be returned for non-english characters unless you specify N forcing unicode.
SELECT 'ук ферт хер' --returns ?? ???? ???
SELECT N'ук ферт хер' --returns ук ферт хер
Most importantly, this has to be done on the insert...
drop table #country
create table #country (names nvarchar(50))
insert into #country(names) values (N'Россия'),('Россия')
SELECT names FROM #country
--Results
--------------------------
names
--------------------------
Россия
??????
-------------------------