Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extracting a string using SQL PATINDEX, substring of varying sizes

I'm trying to extract ###x###, ###x##, and sometimes #x#. Sometimes there may be a space between the numbers and the x. Essentially, I may run into strings like

  • 720x60
  • 720x600
  • 720 x 60
  • 720_x_60
  • 1x1

I use PATINDEX() to find the first occurrence of the pattern '%[0-9]%x%[0-9]%'. So far so good. Then I use PATINDEX() to find the first occurence of a non-digit string after that. This is where I have trouble. I get results as in the screenshot. Code is also below.

SELECT *
    ,CASE WHEN StartInt > 0
        THEN SUBSTRING(Placement, StartInt, SizeLength) ELSE NULL END AS PlacementSize
FROM
(SELECT Placement
    --find the first occurrence of #*x*#
    ,PATINDEX('%[0-9]%x%[0-9]%',Placement) AS StartInt

    --find the first non-digit after that
    ,PATINDEX(
        '%[^0-9]%'
        ,RIGHT(
            Placement + '_' --this underscore adds at least one non-digit to find
            ,LEN(Placement)
                -
            PATINDEX('%[0-9]%x%[0-9]%',Placement) - 5
            )
        ) + 6 AS SizeLength
FROM [Staging].[Client].[A01_FY14_Reporting_staging]
WHERE [Date] > '2014-07-01') AS a

Results:

enter image description here

like image 205
Kyle Avatar asked Sep 12 '14 15:09

Kyle


People also ask

How do I only return part of a string with varying lengths in SQL?

It uses SUBSTRING() to take out a string based on a specific starting character and end character. To determine the start character we look for the first occurrence of : using PATINDEX() and add 2 1 for the space, 1 to move to the starting character. This gives us the starting potion for SUBSTRING()

How do I select a substring in SQL after a specific character?

To find the index of the specific character, you can use the CHARINDEX(character, column) function where character is the specific character at which you'd like to start the substring (here, @ ). The argument column is the column from which you'd like to retrieve the substring; it can also be a literal string.

How do I find the substring of a string in SQL query?

SQL Server CHARINDEX() Function The CHARINDEX() function searches for a substring in a string, and returns the position. If the substring is not found, this function returns 0. Note: This function performs a case-insensitive search.


1 Answers

If you're dealing with a pair of numeric values, but are also dealing with dirty data, and lack the power of Regex, here's what you can do in TSQL.

Essentially, it looks like you're wanting to break the string in half at 'x', then whittle down the outputs until you have numeric only values. Using a set of derived tables, this becomes relatively easy (and not as hard to read)

declare @placements table (Placement varchar(10))
insert into @placements values 
('720x60'),
('720x600'),
('720 x 60'),
('720_x_60'),
('1x1')

SELECT LEFT(LeftOfX,PATINDEX('%[^0-9]%',LeftOfX) - 1) + 'x' + RIGHT(RightOfX, LEN(RightOfX) - PATINDEX('%[0-9]%', RightOfX) + 1)
FROM (
    SELECT RIGHT(LeftOfX, LEN(LeftOfX) - PATINDEX('%[0-9]%', LeftOfX) + 1) AS LeftOfX, LEFT(RightOfX, LEN(RightOfX) - PATINDEX('%[0-9]%', REVERSE(RightOfX)) + 1) AS RightOfX
    FROM (
        SELECT LEFT(p.Placement,x) AS LeftOfX, RIGHT(p.Placement,LEN(p.Placement) - x + 1) AS RightOfX
        FROM (
            SELECT
                  p.Placement
                , CHARINDEX('x',p.Placement) AS x
            FROM @placements p
            ) p
        ) p
    ) p

Here's the SQLFiddle example.

First, select your placement, the location of your 'x' in Placement, and other columns you want from the table. Pass the other columns up through the derived tables.

Next, Split the string into Left and Right.

Process left and right in two more queries, the first to take the right of results starting at the numeric portion, then the left of the results ending at the non-numeric portion.

EDIT: Fixed the outputs, both numbers now selected.

like image 128
Jaaz Cole Avatar answered Sep 24 '22 15:09

Jaaz Cole