How to match numbers that are present between ] and [? - sql

How do I match numbers that are present between ] and [ (not [ and ])?
EDIT-1
In other words, I want to extract those rows where I have a number between ] and [.
My table looks like this...
ID1 id mycolmn
1 100 [ab-ee]43[ddhj]
2 233 [aa-33]49[kl-00]
3 344 [ss-23][wdsd]
And I should get
43
49
EDIT-1 ends
See example file here. I have a column in MyDatabase and I want to extract those rows where there are two digit numbers between ] and [.
Example [ab-ee]43[ddhj] or [aa-33]49[kl-00]
The following did not work.
SELECT * from myTable where [mycolmn] Like "*\]##\[*"

You can use VBA or SQL.
VBA:
Function GetCode(MyColumn As String) As String
Dim RE As New RegExp
Dim colMatches As MatchCollection
With RE
.Pattern = "\]\d\d\["
.IgnoreCase = True
.Global = False
.Multiline = False
Set colMatches = .Execute(MyColumn)
End With
If colMatches.Count > 0 Then
GetCode = Replace(Replace(colMatches(0).Value, "[", ""), "]", "")
Else
GetCode = ""
End If
End Function
And you would call it like this:
SELECT GetCode([test]) AS MyDigits
FROM test;
If you want a strait SQL solution:
SELECT Mid([test],InStr([test],"]")+1,2) AS MyDigits
FROM test;
This assumes that your numbers come after the first ]. If not, it can be modified with more IIF, INSTR, & MID functions to match your pattern. It would be ugly, but it can work.

Yo dawg I heard you like brackets so I put brackets in your brackets so you can escape your brackets
Select * FROM yourTable WHERE MAtch LIKE "*]##[ [ ]*"

Select Mid([MyColumn],InStr([MyColumn],"]")+1,2) AS MyDigits
FROM yourTable WHERE [MyColumn] LIKE "*]##[ [ ]*"
Please award the check if this answer suits your needs. That's how StackOverflow works.

You can try PATINDEX:
create table TestPatIndex
(
MyData varchar(100)
)
insert into TestPatIndex select '[ab-ee]43[ddhj]'
insert into TestPatIndex select '[ab-ee]XX[ddhj]'
select SUBSTRING(MyData, PATINDEX ('%][0-9][0-9][[]%', MyData ) + 1, 2)
from TestPatIndex
where isnumeric(SUBSTRING(MyData, PATINDEX ('%][0-9][0-9][[]%', MyData ) + 1, 2)) = 1
Here is a link to SQL fiddle.
Something like this should work in MS Access:
SELECT MyData AS Expr1
FROM TestPatIndex
where MyData like '*][0-9][0-9][[]*'

Related

GET particular value from split string result in sql

I FIRE BELOVED QUERY
SELECT value
FROM STRING_SPLIT('3G-4RPE-L250-S80-27K-UNV-DIM-WT-RG1-CP-S(9)', '-')
I GOT FOLLOWING RESULT
VALUE
3G
4RPE
L250
S80
27K
UNV
DIM
WT
RG1
CP
S(9)
IS IT POSSIBLE TO GET PARTICULAR WORD LIKE 4RPE, RG1 FROM ABOVE RESULT SET IN SQL?
One option is with a bit of JSON. Here we convert your string into a JSON Array. Then it becomes a small matter to extract the values.
Example
Declare #S varchar(max) = '3G-4RPE-L250-S80-27K-UNV-DIM-WT-RG1-CP-S(9)'
Set #S = '["'+replace(string_escape(#S,'json'),'-','","')+'"]'
Select Pos1 = JSON_VALUE(#S,'$[1]')
,Pos8 = JSON_VALUE(#S,'$[8]')
Results
Pos1 Pos8
4RPE RG1
2nd Option
Select *
From OpenJSON(#S)
Where [key] in (1,8)
Results
key value type
1 4RPE 1
8 RG1 1

How to check if string ends in date and strip result? - SQL

I'm trying to check whether or not a string ends in a year.
Input:
file_paths
wowefnowinf/wefionwe/wefowoi/2012-02-03
weofnweofn/weoew/2022-03-04
ewpfowe/ewopfew
Desired Output:
wowefnowinf/wefionwe/wefowoi/
weofnweofn/weoew/
ewpfowe/ewopfew
I'm having trouble first detecting that the strings themselves end in a date-format. This is my query:
SELECT CASE WHEN 'wowefnowinf/wefionwe/wefowoi/2012-02-03' LIKE '%/####\-##\-##'
THEN TRUE
ELSE FALSE END AS result
FROM my_table;
I should be getting true for this, but my query returns false. Any help would be appreciated.
In Snowflake you can make use of regexp_like and split_part:
with dummy as (
select 'wowefnowinf/wefionwe/wefowoi/2012-02-03' as file_path
union all
select 'weofnweofn/weoew/2022-03-04'
union all
select 'ewpfowe/ewopfew'
)
select
file_path,
split_part(file_path, '/', -1) as splitted_file_path,
regexp_like(splitted_file_path, '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]') as ends_with_date,
iff(ends_with_date, trim(file_path, splitted_file_path), file_path) as trimmed_file_path
from dummy;
Output:

If statement in SQL how to do it

I've got an if statement (below) which runs in Tableau. I need to turn this into SQl - I've tried lots of different case statements, but they all get errors.
Can anyone advise how I'd do this?
IF LEN(REPLACE([postcode]," ","")) = 7 THEN LEFT(REPLACE([postcode]," ",""),4)+" "+RIGHT(REPLACE([postcode]," ",""),3)
ELSEIF LEN(REPLACE([postcode]," ","")) = 6 THEN LEFT(REPLACE([postcode]," ",""),3)+" "+RIGHT(REPLACE([postcode]," ",""),3)
ELSEIF LEN(REPLACE([postcode]," ","")) = 5 THEN LEFT(REPLACE([postcode]," ",""),2)+" "+RIGHT(REPLACE([postcode]," ",""),3)
END
Try to use this:
SELECT
CASE
WHEN LEN(REPLACE([postcode],' ','')) = 7
THEN LEFT(REPLACE([postcode],' ',''),4)+' '+RIGHT(REPLACE([postcode],' ',''),3)
WHEN LEN(REPLACE([postcode],' ','')) = 6
THEN LEFT(REPLACE([postcode],' ',''),3)+' '+RIGHT(REPLACE([postcode],' ',''),3)
WHEN LEN(REPLACE([postcode],' ','')) = 5
THEN LEFT(REPLACE([postcode],' ',''),2)+' '+RIGHT(REPLACE([postcode],' ',''),3)
ELSE 'ERROR'
END
FROM YOUR_TABLE
As the OP stated after some querying, he is using Hive on Hadoop - not plain SQL.
So - maybe - this could get you started: https://de.hortonworks.com/blog/hive-cheat-sheet-for-sql-users/
You could just replace the IF in your statement by CASE WHEN
And all the ELSEIF by WHEN
But you can probably also simplify it to :
CASE
WHEN LEN(REPLACE([POSTCODE]," ","")) IN (5,6,7) THEN REPLACE ([POSTCODE]," ","")
ELSE NULL
END
Since f.e. "ABC" + "DEF" = "ABCDEF" = "ABC DEF" without spaces.

How to split a column by the number of white spaces in it with SQL?

I've got a single column that contains a set of names in it. I didn't design the database so that it contains multiple values in one column, but as it is I've got to extract that information now.
The problem is that in one field I've got multiple values like in this example:
"Jack Tom Larry Stan Kenny"
So the first three should be one group, and the other ones on the far right are another group. (Basically the only thing that separates them in the column is a specific number of whitespace between them, let's say 50 characters.)
How can I split them in pure SQL, so that I can get two columns like this:
column1 "Jack Tom Larry"
column2 "Stan Kenny"
A fairly simplistic answer would be to use a combination of left(), right() and locate(). Something like this (note I've substituted 50 spaces with "XXX" for readability):
declare global temporary table session.x(a varchar(100))
on commit preserve rows with norecovery;
insert into session.x values('Jack Tom LarryXXXStan Kenny');
select left(a,locate(a,'XXX')-1),right(a,length(a)+1-(locate(a,'XXX')+length('XXX'))) from session.x;
If you need a more general method of extracting the nth field from a string with a given separator, a bit like the split_part() function in PostgreSQL, in Ingres your options would be:
Write a user defined function using the Object Management Extension (OME). This isn't entirely straightforward but there is an excellent example in the wiki pages of Actian's community site to get you started:
http://community.actian.com/wiki/OME:_User_Defined_Functions
Create a row-producing procedure. A bit more clunky to use than an OME function, but much easier to implement. Here's my attempt at such a procedure, not terribly well tested but it should serve as an example. You may need to adjust the widths of the input and output strings:
create procedure split
(
inval = varchar(200) not null,
sep = varchar(50) not null,
n = integer not null
)
result row r(x varchar(200)) =
declare tno = integer not null;
srch = integer not null;
ptr = integer not null;
resval = varchar(50);
begin
tno = 1;
srch = 1;
ptr = 1;
while (:srch <= length(:inval))
do
while (substr(:inval, :srch, length(:sep)) != :sep
and :srch <= length(:inval))
do
srch = :srch + 1;
endwhile;
if (:tno = :n)
then
resval=substr(:inval, :ptr, :srch - :ptr);
return row(:resval);
return;
endif;
srch = :srch + length(:sep);
ptr = :srch;
tno = :tno + 1;
endwhile;
return row('');
end;
select s.x from session.x t, split(t.a,'XXX',2) s;

Select part of word from query?

In Access, I have a field like this:
From the start until end at 01/05/2013, the XXXXXXX device was used.
I'm looking for a query that can extract the device name (in this case XXXXXXX). I was able to use mid() to get it somewhat working, but the sentence could be longer or shorter. What are some other ways to do this? Is there a find() I can use to find the location of "device"?
My SQL looks like:
SELECT Mid(Note, 68, 30)
FROM My_Log
WHERE Note LIKE "*, the*"
;
If the device name is the word before "device", and you want to find that word using only functions supported directly by the Access db engine, Mid(), InStr(), and InstrRev() can get the job done ... but it won't be pretty.
Here is an Immediate window session ...
Note = "From the start until end at 01/05/2013, the XXXXXXX device was used."
? Mid(Note, _
InstrRev(Note, " ", InStr(1, Note, " device") -1) +1, _
InStr(1, Note, " device") - InstrRev(Note, " ", InStr(1, Note, " device") -1) -1)
XXXXXXX
So you would then need to use that complex Mid() expression in a query.
However, if you can use a user-defined function in your query, the logic could be easier to manage.
Public Function FindDevice(ByVal pInput As String) As Variant
Dim astrWords() As String
Dim i As Long
Dim lngUBound As Long
Dim varReturn As Variant
varReturn = Null
astrWords = Split(pInput, " ")
lngUBound = UBound(astrWords)
For i = 0 To lngUBound
If astrWords(i) = "device" Then
varReturn = astrWords(i - 1)
Exit For
End If
Next i
FindDevice = varReturn
End Function
Then the query could be ...
SELECT FindDevice(Note) AS device_name
FROM My_Log
WHERE Note LIKE "*, the*"
If you know the name of the device, you can use Instr:
... WHERE Instr([Note], "Mydevice")>0
You can also use a table that lists devices:
SELECT Note FROM MyTable, ListTable
WHERE Note Like "*" & ListTable.Devices & "*"
Re comment:
SELECT Note
FROM MyTable
WHERE [Note] Like "*" & [enter device] & "*"
If you need to know where in notes you will find device
SELECT Note, InStr([Note],[enter device]) ...
In addition to my comments this is Oracle query that may help you. Replace dual with with your table name and query should probably work. As I mentioned all functions I'm using in this query are ANSI SQL standard. The syntax you can fix yourself. You may run all queries separately to get start, end positions and lenght of your machine name, etc...:
SELECT SUBSTR(str, start_pos, end_pos) machine_name
FROM
(
SELECT str, INSTR(str,'XXXXXXX') start_pos, Length('XXXXXXX') end_pos
FROM
(
SELECT 'From the start until end at 01/05/2013, the XXXXXXX device was used.' str FROM dual
)
)
/
SQL>
MACHINE
-------
XXXXXXX
More generic approach with the same result - eliminating Length:
SELECT SUBSTR(str_starts, 1, end_pos) machine_name FROM -- Final string
(
SELECT str_starts, INSTR(str_starts, ' ')-1 end_pos FROM -- end pos = last X pos in string starts - in 'XXXXXXX'
(
SELECT SUBSTR(str, start_pos) str_starts FROM -- strig starts from first X
(
SELECT str, INSTR(str,'XXXXXXX') start_pos FROM -- start_pos
(
SELECT 'From the start until end at 01/05/2013, the XXXXXXX device was used.' str FROM dual
))))
/