In SQL, in order to grab n characters from the left side of a string, you can use the LEFT function:
SELECT LEFT('Hello World', 5)
-- "Hello"
There doesn't appear to be a left or right function in the docs on scalar functions:
Q: How do you do select left most characters in KQL?
You can use the substring function:
substring(source, startingIndex [, length])
LEFT
SQL: SELECT LEFT('Hello World', 5)
KQL: print substring("Hello World", 0, 5)
RIGHT
SQL: SELECT RIGHT('Hello World', 5)
KQL: print substring("Hello World", -5, 5)
Related
For Eg; abc.def.efg , separate into independent strings as abc def efg
Head
abc.def.efg
to
left
center
right
abc
def
efg
On SQL Server with a 3-part delimited string you can use parsename
with t as (
select 'left.centre.right' Head
)
select ParseName(Head,3) L, ParseName(Head,2) C, ParseName(Head,1) R
from t;
on MySQL, you can do:
with t as (
select 'left.centre.right' Head
)
select
substring_index(Head,'.',1) as L,
substring_index(substring_index(Head,'.',2),'.',-1) as M,
substring_index(Head,'.',-1) as R
from t;
results:
L
M
R
left
centre
right
see: DBFIDDLE, and DOCS
Look into the split_part() equivalent for the RDBMS you're using.
E.g.
SELECT
split_part(Head, '.', 1) AS "left",
split_part(Head, '.', 2) AS center,
split_part(Head, '.', 3) AS "right"
FROM your_table
EDIT: corrected the indexes, see: https://www.postgresqltutorial.com/postgresql-split_part/
I am giving input word is "hello"
My output will be print as mentioned below using SQL query not pl/sql.
h
e
l
l
o
You can use SUBSTR() function within a hierarchical query such as
SELECT SUBSTR(col,level,1) AS "letters"
FROM t
CONNECT BY level <= LENGTH(col)
presuming your DB is Oracle from the keyword PL/SQL
Use like this
select substring(a.b, v.number+1, 1)
from (select 'hellow' b) a
join master..spt_values v on v.number < len(a.b)
where v.type = 'P'
You didn't mention your DBMS, but in Postgres you can use:
select *
from unnest(string_to_array('hello', null));
Here is another way to do this in oracle
select 'hello'
,substr('hello',rownum,1) as vertical_str
from dual a
join all_tables b
on 1=1
where rownum<=length('hello')
h
e
l
l
o
Another option is a recursive CTE.
WITH
word
(word)
AS
(
SELECT 'hello' word
FROM dual
),
letter
(letter,
remainder)
AS
(
SELECT substr(word, 1, 1) letter,
substr(word, 2) remainder
FROM word
UNION ALL
SELECT substr(remainder, 1, 1) letter,
substr(remainder, 2) remainder
FROM letter
WHERE remainder IS NOT NULL
)
SELECT letter
FROM letter;
db<>fiddle
I am assuming Oracle here as you mentioned PL/SQL. But for other DBMS this would be pretty similar -- the substr() function might be called substring(), instead of a NULL you'd have to check for remainder to be the empty string and the RECURESIVE keyword might be needed for the second CTE.
I have a problem where a eastern-arabic numeral has entered my table as a timestamp and bigquery doesn't recognise this as a timestamp and will not execute my queries.
I wish to be able to convert this:
'٢٠١٨-١٠-١١T١٦:٠١:٤١.٠٤١Z'
into this:
'2018-10-11T16:01:41.041Z
in bigquery, Is this possible?
How about this SQL UDF:
CREATE TEMP FUNCTION arabicConvert(input STRING) AS ((
SELECT STRING_AGG(COALESCE(FORMAT('%i', i), letter), '')
FROM (SELECT SPLIT(input, '') x), UNNEST(x) letter
LEFT JOIN (SELECT letter_dict,i FROM (
SELECT SPLIT('٠١٢٣٤٥٦٧٨٩', '') l), UNNEST(l) letter_dict WITH OFFSET i
)
ON letter=letter_dict
));
SELECT arabicConvert('٢٠١٨-١٠-١١T١٦:٠١:٤١.٠٤١Z') converted
2018-10-11T16:01:41.041Z
There is alternative, lighter option :o)
CREATE TEMP FUNCTION arabicNumeralsConvert(input STRING) AS ((
CODE_POINTS_TO_STRING(ARRAY(
SELECT IF(code > 1600, code - 1584, code)
FROM UNNEST(TO_CODE_POINTS(input)) code
))
));
WITH t AS (
SELECT '٢٠١٨-١٠-١١T١٦:٠١:٤١.٠٤١Z' str UNION ALL
SELECT '2018-10-12T20:34:57.546Z'
)
SELECT str, arabicNumeralsConvert(str) converted
FROM t
result is as
str converted
٢٠١٨-١٠-١١T١٦:٠١:٤١.٠٤١Z 2018-10-11T16:01:41.041Z
2018-10-12T20:34:57.546Z 2018-10-12T20:34:57.546Z
SELECT REPLACE('ABCTemplate1', 'Template\d+', '');
SELECT REPLACE('ABC_XYZTemplate21', 'Template\d+', '');
I am trying to remove the part Template followed by n digits from a string. The result should be
ABC
ABC_XYZ
However REPLACE is not able to read regex. I am using SQLSERVER 2008. Am I doing something wrong here? Any suggestions?
SELECT SUBSTRING('ABCTemplate1', 1, CHARINDEX('Template','ABCTemplate1')-1)
or
SELECT SUBSTRING('ABC_XYZTemplate21',1,PATINDEX('%Template[0-9]%','ABC_XYZTemplate21')-1)
More generally,
SELECT SUBSTRING(column_name,1,PATINDEX('%Template[0-9]%',column_name)-1)
FROM sometable
WHERE PATINDEX('%Template[0-9]%',column_name) > 0
You can use substring with charindex or patindex if the pattern being looked for is fixed.
select SUBSTRING('ABCTemplate1',1, CHARINDEX ( 'Template' ,'ABCTemplate1')-1)
My answer expects that "Template" is enough to determine where to cut the string:
select LEFT('ABCTemplate1', CHARINDEX('Template', 'ABCTemplate1') - 1)
Using numbers table..
;with cte
as
(select 'ABCTemplate1' as string--this can simulate your table column
)
select * from cte c
cross apply
(
select replace('ABCTemplate1','template'+cast(n as varchar(2)),'') as rplcd
from
numbers
where n<=9
)
b
where c.string<>b.rplcd
Using Recursive CTE..
;with cte
as
(
select cast(replace('ABCTemplate21','template','') as varchar(100)) as string,0 as num
union all
select cast(replace(string,cast(num as varchar(2)),'') as varchar(100)),num+1
from cte
where num<=9
)
select top 1 string from cte
order by num desc
I have this query which tries to capture the last 11 characters excluding the semi colon at the end of the date(string). But when I run the script it returns value which is not included in the string, and im stuck for days.
Here's my query
select TOP 2 a.ACCOUNT,a.GPSDATE,
SUBSTRING(b.smsmsg, LEN(b.smsmsg) - 10, 6) [KM2]
from TblGPSCur a
inner join GPRSIN b on a.ACCOUNT = b.SMSFR
where exists(select * from GPRSIN b where b.SMSFR = a.ACCOUNT
and b.smsdt between '2014-10-27 14:00:00' and '2014-10-27 14:49:54')
THE RESULT IS THIS
This is the top 2 data im trying to parse
The result should be 277511767.8
Can anyone tell me where I might be doing wrong on this one?
You can use RIGHT() function of SQL like this -
SELECT TOP 2 a.ACCOUNT
,a.GPSDATE
RIGHT(b.smsmsg, 11) [KM2]
FROM TblGPSCur a
INNER JOIN GPRSIN b ON a.ACCOUNT = b.SMSFR
WHERE EXISTS (
SELECT *
FROM GPRSIN b
WHERE b.SMSFR = a.ACCOUNT
AND b.smsdt BETWEEN '2014-10-27 14:00:00'
AND '2014-10-27 14:49:54'
)
You have your SUBSTRING() setup incorrectly, it should be:
SELECT SUBSTRING(b.smsmsg, LEN(b.smsmsg) - 11, 11)
As the starting position is LEN(x) - 11, and you want 11 characters after that point.
Alternately, you can use LEFT() and RIGHT():
declare #SillyLongString as nvarchar(100)
set #SillyLongString = '1234567890a;s.a.dpoiuytghjkmnbvfg,277511767.8;'
select left(right(#SillyLongString, 12),11)
-- outputs: 277511767.8
This selects the 12 right-most characters and then takes the first 11 characters from that string.
Adding to your query:
select TOP 2 a.ACCOUNT,a.GPSDATE,
left(right(b.smsmsg, 12),11) [KM2] ...