Convert regexp_substr statement to SQL Server equivalent - sql

I am new to converting oracle sql statement to t-sql. Can you please help me convert the following statement?
select regexp_substr(TO_CHAR(X.ITEM), '[^|]+', 1, level) CONCAT
from dual
connect by regexp_substr(TO_CHAR(X.ITEM), '[^|]+', 1, level) is not null

It looks like you want to split a delimited list into rows, using character | as separator.
If you are running SQL Server 2016 or higher, you can use string_split() for this. Assuming that x is the table where item is stored, you would go:
select x.*, value
from x
cross apply string_split(item, '|')

Related

SUBSTR in sql oracle from right

I have data in table 000_ABC_AXEL. The expectation is that i have to exclude data after the last '_' and get 000_ABC in oracle sql? Any suggestions?
Need sql query to achieve below
for ex:
a_222_4 -- > expected result :a_222
123_xyz_0 -- >expected result :123_xyz
A regex replacement fits your requirement nicely:
SELECT col, REGEXP_REPLACE(col, '_[^_]+$', '') AS col_out
FROM yourTable;
You can do it with simple string functions (which are much faster than regular expressions) by finding the sub-string up to the character before the last underscore:
SELECT SUBSTR(col, 1, INSTR(col, '_', -1) - 1) AS first_parts
FROM table_name;
Which, for the sample data:
CREATE TABLE table_name (col) AS
SELECT 'a_222_4' FROM DUAL UNION ALL
SELECT '123_xyz_0' FROM DUAL;
Outputs:
FIRST_PARTS
a_222
123_xyz
fiddle

CAST - Make string length to be 2 characters long

I need to combine two fields but force the characters of the second string to be 2 characters.
I'm combining a year field and month field and want the result to be YYYY_MM. Forcing any single months (e.g. 1,2,3,4) into a two digit format e.g. (01).
Below is my formula for combining the fields, but I need help making the month two digits.
Thanks, L
WITH so_header(soh_build_year,soh_build_week) AS (
SELECT 2020, 3
UNION ALL SELECT 2020,13
)
SELECT
CAST(SO_HEADER.SOH_Build_Year AS VARCHAR)
+'_'
+CAST(SO_HEADER.SOH_Build_Week AS VARCHAR) as [Build YYYY_WW]
FROM so_header;
Try this out (Syntax: SQL Server)
SELECT
CAST(2019 AS VARCHAR)
+'_'
+CAST(format (1, '0#') AS VARCHAR) as [Build YYYY_WW]
Replace your values with your variables
Try this:
WITH so_header(soh_build_year,soh_build_week) AS (
SELECT 2020, 3
UNION ALL SELECT 2020,13
)
SELECT
CAST(SO_HEADER.SOH_Build_Year AS VARCHAR)
+ '_'
+ SUBSTR(
CAST(100+SO_HEADER.SOH_Build_Week AS VARCHAR)
, 2
, 2
) as Build_YYYY_WW
FROM so_header;
-- out Build_YYYY_WW
-- out ---------------
-- out 2020_03
-- out 2020_13
If you are using SQL Server never use varchar (or related types) with no length. The default varies by context and may not be large enough for what you want.
If you are trying to convert a date to YYYY_MM format, you can use format():
select format(getdate(), 'yyyy_MM')
I recommend using dates, if they are available. If you are not using SQL Server, most other databases have similar functionality.
If not, you an simply use:
select concat(so_header.SOH_Build_Year, '_'
right(concat('00', so_header.soh_build_week), 2)
)
concat() does not require explicitly converting the values to strings.

how to split the value in oracle

I have worked with MySQL and new to oracle. In MySQL we have a function SUBSTRING_INDEX(), I want to replace it in oracle, Any help plz
SQL>select SUBSTRING_INDEX('JD;EQ;0001', ';', -1) from dual;
Result:
0001
I want a same result in oracle. Is there any function in oracle that return the same result in oracle?
I have tried but no expected result.
SELECT substr('CLUBORACLE',3,2) RES FROM dual;
SELECT SUBSTR('JD;EQ;0001', INSTR('JD;EQ;0001', ';', -1) + 1) FROM dual
In the query above, INSTR('JD;EQ;0001', ';', -1) would return 6, which is the position of the last semicolon in the expression. You want to take the substring from the position after the last semicolon until the end of the string.
Look here for a good SO question about Oracle's INSTR.
You can also use regex: SELECT REGEXP_SUBSTR('JD;EQ;0001', '[^;]+', 1, your_occurance_number) FROM dual; but SUBSTR+INSTR should be faster.

How to calculate the number of occurrences of a character in a varchar in a single SQL?

Say there is a variable
v_Source := 'stack#over#flo#w';
How to get the number of occurrences of '#' in it in a single SQL query?
select length('stack#over#flo#w') - length(replace('stack#over#flo#w','#',null))
from dual;
From oracle 11 you can use REGEXP_COUNT
select REGEXP_COUNT('stack#over#flo#w', '#') from dual;
SELECT REGEXP_COUNT( 'stack#over#flo#w', '#' )
FROM DUAL

Formatting an SQL numeric query result with an arbitrary number of decimal places

I have a database table with these two columns:
Amount: numeric (18,0)
DecimalPlaces: numeric (18,0)
This table can store amounts in various currencies, with the decimal place removed from the amount (I can't change this data model). For example, there might be two rows like this:
1290, 2 (This is £12.90, needs to appear as "12.90")
3400, 0 (This is 3400 Japanese Yen, needs to appear as "3400")
I need an SQL query for both Oracle and SQL Server that will format each amount with the correct number of decimal places, preserving any trailing zeroes as illustrated above. I can't use stored procedures, a reporting tool, or Excel.
Your problem is that there isn't an easy way to do this for both SQLServer and Oracle in one query.
The Correct way to do this for SQLServer is to use STR:
Select STR(Amount, 18, DecimalPlaces) from myTable;
The correct way to do this for Oracle is using to_char:
SELECT to_char (amount, '99999999999999.'||rpad('',DecimalPlaces, '0'))
from MyTable;
The queries presented by jms and Andrew won't work in an Oracle query because Oracle SQL uses LENGTH() not LEN(). And Oracle uses to_char() not Cast().
The best I've been able to come up with so far is:
select Amount/power(10, DecimalPlaces) from MyTable
But it doesn't do exactly what I want:
Oracle: the trailing zeroes are stripped, so US$15.00 looks like "15", not "15.00"
SQL Server: a whole lot of extra trailing zeroes are added, so $23.99 looks like "23.99000000000" instead of "23.99"
How about?
select 12345 amount, 2 decimalPlaces, substr( to_char( 12345 ), 1, length (to_char( 12345 ) ) - 2 )
|| '.' || substr( to_char( 12345 ), -2 ) result from dual
/
amount decimalPlaces result
---------- ------------- ------
12345 2 123.45
This is gross but worked for the current inputs on SQL server.
select
substring(
CAST(
CAST(
(amount * power(-0.100000000000000000,decimalPlaces*1.000000000000000000)) as numeric(36,18)
)as varchar(30)
)
,1,len(cast(amount as varchar(20))) + (CASE WHEN decimalPlaces = 0 THEN 0 ELSE 1 END ))
from
myTable
In SQL server you can :
select stuff(convert(varchar,amount) ,
len(convert(varchar,amount)) - DecimalPlaces - 1, 0, ".")
Martlark's answer for Oracle led me to this solution for SQL Server:
select
left(cast(Amount as varchar), len(cast(Amount as varchar)) - DecimalPlaces) +
left('.', DecimalPlaces) +
right(cast(OriginalCurrencyAmount as varchar), DecimalPlaces
) as FormattedAmount
from MyTable