Query help

  • I have a function dbo.fn_ConvertToNumeric(@a) and am using it in an update statement for a table having millions of records.

    update tbl_source

    set Col1 = case when col2 = 'abc'

    then dbo.fn_ConvertToNumeric(col3) end

    Col3 may or may not have values suffix (like -xyz, -abc etc) which is getting removed by the function.

    Now i have to add one more logic where when col2 = 'abc' then case when len(col3) > 10 and col3 like '111%' then i've to pick substring(col3, 4, len(col3)) end else dbo.fn_ConvertToNumeric(col3) end.

    I want to write it in efficient way so that my overall process does not have to bear cost of one additional update.

  • If I understand you....

    UPDATE tbl_source

    SET Col1 = CASE WHEN LEN(col3) > 10 AND col3 LIKE '111%'

    THEN SUBSTRING(col3, 4, LEN(col3) ELSE dbo.fn_ConvertToNumeric(col3) END

    WHERE col2 = 'abc';

    using a WHERE clause to reduce the number of updates.

  • This is simplest one and i tried it by my own. It will not consider the values like

    col3 = 11123456789-xyz

    In this case it should be 23456789

  • What i'm looking for is any update like this:

    UPDATE tbl_source

    SET Col1 = CASE WHEN LEN(dbo.fn_ConvertToNumeric(col3)) > 10 AND dbo.fn_ConvertToNumeric(col3) LIKE '111%' THEN SUBSTRING(dbo.fn_ConvertToNumeric(col3), 4, LEN(dbo.fn_ConvertToNumeric(col3)) ELSE dbo.fn_ConvertToNumeric(col3) END

    WHERE col2 = 'abc';

    But it doesn't feel good to me calling same function five times in the update.

  • If you're updating all those rows, you should consider changing your scalar function to an inLine table-valued function. It will boost your performance.

    If you need help on how to do it, post sample data, rules and expected results for the function.

    Luis C.
    General Disclaimer:
    Are you seriously taking the advice and code from someone from the internet without testing it? Do you at least understand it? Or can it easily kill your server?

    How to post data/code on a forum to get the best help: Option 1 / Option 2
  • If the function just removes an optional trailing '-' followed by other chars, you can avoid a function completely using CROSS APPLY:

    UPDATE ts

    SET

    Col1 = CASE WHEN LEN(col3_num) > 10 AND col3_num LIKE '111%'

    THEN SUBSTRING(col3_num, 4, 20)

    ELSE col3_num END

    FROM tbl_source ts

    CROSS APPLY (

    SELECT LEFT(col3, CHARINDEX('-', col3 + '-') - 1) AS col3_num

    ) AS cross_apply_1

    WHERE

    Col2 = 'abc'

    Note that this code is not identical to your original code. Your original code would have updated every row, this code only updates rows where Col2 = 'abc'.

    SQL DBA,SQL Server MVP(07, 08, 09) "It's a dog-eat-dog world, and I'm wearing Milk-Bone underwear." "Norm", on "Cheers". Also from "Cheers", from "Carla": "You need to know 3 things about Tortelli men: Tortelli men draw women like flies; Tortelli men treat women like flies; Tortelli men's brains are in their flies".

  • ScottPletcher (2/13/2014)


    If the function just removes an optional trailing '-' followed by other chars, you can avoid a function completely using CROSS APPLY:

    UPDATE ts

    SET

    Col1 = CASE WHEN LEN(col3_num) > 10 AND col3_num LIKE '111%'

    THEN SUBSTRING(col3_num, 4, 20)

    ELSE col3_num END

    FROM tbl_source ts

    CROSS APPLY (

    SELECT LEFT(col3, CHARINDEX('-', col3 + '-') - 1) AS col3_num

    ) AS cross_apply_1

    WHERE

    Col2 = 'abc'

    Note that this code is not identical to your original code. Your original code would have updated every row, this code only updates rows where Col2 = 'abc'.

    Thanks Scott. But my data in col3 mostly contains numeric but may contain very less amount of alphanumeric characters as well. Something goes like this:

    Col3

    123454321

    12345678-ABC

    10123456789

    10123456789-A

    11199999999

    11122222222-X

    In this case the function gives value as

    Col3

    123454321

    12345678

    10123456789

    11199999999

    11122222222

    Result i want is

    Col3

    123454321

    12345678

    10123456789

    99999999 -- removed 111

    22222222 -- removed 111

  • I can't find the problem you mention. Maybe the sample data is wrong.

    WITH tbl_source AS(

    SELECT Col2, Col3

    FROM (VALUES('abc','123454321'),

    ('abc','12345678-ABC'),

    ('abc','10123456789'),

    ('abc','10123456789-A'),

    ('abc','11199999999'),

    ('abc','11122222222-X'))x(Col2, Col3)

    )

    SELECT Col1 = CASE WHEN LEN(col3_num) > 10 AND col3_num LIKE '111%'

    THEN SUBSTRING(col3_num, 4, 20)

    ELSE col3_num END

    FROM tbl_source ts

    CROSS APPLY (

    SELECT LEFT(col3, CHARINDEX('-', col3 + '-') - 1) AS col3_num

    ) AS cross_apply_1

    WHERE

    Col2 = 'abc'

    Luis C.
    General Disclaimer:
    Are you seriously taking the advice and code from someone from the internet without testing it? Do you at least understand it? Or can it easily kill your server?

    How to post data/code on a forum to get the best help: Option 1 / Option 2

Viewing 8 posts - 1 through 7 (of 7 total)

You must be logged in to reply to this topic. Login to reply