some UDF FUnction help, please....

  • I would like to turn a ranking statement into a function.. . I THINK I need a Table valued function, but I'm not sure, and I don't do well with functions since I never write them. If someone would help me get this right, I would get me started as I see lots of possiblities. I've included a script to create a temp table, populate it, and run the query with the ranking function.

    You're help is GREATLY appreciated...

    [Code]

    If OBJECT_ID('tempdb..#Crusty_Table') is not null

    Begin

    Drop table #Crusty_Table

    End

    Create table #Crusty_Table (

    UniqueIDvarchar(255),

    RecordingDatevarchar(255)

    )

    Insert Into #Crusty_Table(UniqueId, RecordingDate)

    Select '123738','05/21/1969' UNION All

    Select '123738','06/09/2010' UNION All

    Select '123738','05/29/1967' UNION All

    Select '123738','05/29/1967' UNION All

    Select '123738','05/31/1967' UNION All

    Select '123456','07/09/1977' UNION All

    Select '123456','05/29/1967' UNION All

    Select '123457','06/09/2010' UNION All

    Select '123457','05/21/1969' UNION All

    Select '123457','07/09/1977' UNION All

    Select '123457','03/07/2007' UNION All

    Select '123458','01/15/2014'

    Select *

    from #Crusty_Table

    ---------------------------------------------------

    ---- This is the money shot -----------------------

    ---------------------------------------------------

    select Distinct UniqueID, RecordingDate

    --, ROW_NUMBER() over (Partition by UniqueID Order by RecordingDate)

    , CASE When (ROW_NUMBER() over (Partition by UniqueID Order by RecordingDate)) = 1 THEN UniqueID

    Else UniqueID + '-' + Convert(varchar(255),ROW_NUMBER() over (Partition by UniqueID Order by RecordingDate)-1)

    END UniqueID_Alt

    From #Crusty_Table

    [/code]

  • I assume your temp table is a persistent table in your actual system? something like this?

    CREATE FUNCTION dbo.MyInlineTableValueFunction()

    RETURNS TABLE WITH SCHEMABINDING AS

    RETURN

    select Distinct UniqueID, RecordingDate

    --, ROW_NUMBER() over (Partition by UniqueID Order by RecordingDate)

    , CASE When (ROW_NUMBER() over (Partition by UniqueID Order by RecordingDate)) = 1 THEN UniqueID

    Else UniqueID + '-' + Convert(varchar(255),ROW_NUMBER() over (Partition by UniqueID Order by RecordingDate)-1)

    END UniqueID_Alt

    From YourPersistent_Crusty_Table

    ;

    GO

    _______________________________________________________________

    Need help? Help us help you.

    Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.

    Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.

    Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
    Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
    Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
    Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/

  • I would use a persistent temp table rather than a table variable for your purpose.

    Basically you need to clear the temp table, insert records, and then use Sean's function to get the result.

    Table variable is difficult to maintain (making a change) and its performance is another concern.

  • A lot of extra work when it isn't really needed if you ask me.

    If OBJECT_ID('tempdb..#Crusty_Table') is not null

    Begin

    Drop table #Crusty_Table

    End

    Create table #Crusty_Table (

    UniqueIDvarchar(255),

    RecordingDatedate

    )

    Insert Into #Crusty_Table(UniqueID, RecordingDate)

    Select '123738','05/21/1969' UNION All

    Select '123738','06/09/2010' UNION All

    Select '123738','05/29/1967' UNION All

    Select '123738','05/29/1967' UNION All

    Select '123738','05/31/1967' UNION All

    Select '123456','07/09/1977' UNION All

    Select '123456','05/29/1967' UNION All

    Select '123457','06/09/2010' UNION All

    Select '123457','05/21/1969' UNION All

    Select '123457','07/09/1977' UNION All

    Select '123457','03/07/2007' UNION All

    Select '123458','01/15/2014'

    Select *

    from #Crusty_Table

    ---------------------------------------------------

    ---- This is the money shot -----------------------

    ---------------------------------------------------

    select Distinct UniqueID, RecordingDate

    --, ROW_NUMBER() over (Partition by UniqueID Order by RecordingDate)

    , CASE When (ROW_NUMBER() over (Partition by UniqueID Order by RecordingDate)) = 1 THEN UniqueID

    Else UniqueID + '-' + Convert(varchar(255),ROW_NUMBER() over (Partition by UniqueID Order by RecordingDate)-1)

    END UniqueID_Alt

    From #Crusty_Table

    GO

    with basedata as (

    select

    UniqueID,

    RecordingDate,

    rn = row_number() over (partition by UniqueID order by RecordingDate)

    from

    #Crusty_Table

    )

    select

    bd.UniqueID,

    bd.RecordingDate,

    case when bd.rn = 1 then bd.UniqueID else bd.UniqueID + '-' + cast(bd.rn - 1 as varchar) end

    from

    basedata bd

    If OBJECT_ID('tempdb..#Crusty_Table') is not null

    Begin

    Drop table #Crusty_Table

    End

    go

  • FYI, I changed the RecordingDate data type from varchar(255) to date (since this is a SQL Server 2008 forum). Dates really should be stored using the correct data type.

  • Lynn,

    Saw this while I was doing dishes... LOL It's mothers day...

    Anyway, thanks for the reply. There is a very specific reason that fields are data type varchar(255). Actually, we keep them at 500 for all fields. The reason is that we are importing data from county databases that contain property information. The information, since people are the ones that manually key it in, is fraught with mistakes and very interesting entries.. Some examples would be Jan 32, 2069. That was fairly recent. If I shoved that date into a DateTime field, it would bounce back and yell at me... I'm married, so I get yelled at often enough 😀

    Either way, for the purpose of just getting into the database from it's raw-flat file format, we constantly run into issues, so it's easier to keep it at varchar datatypes then what is correct.

    I REALLY REALLY REALLY appreciate the help I get in this forum.. I really really do....

    Thanks

    and... if you're a mom.. Happy Mother's Day...(actually, I know a guy named Lynn... Hmmmm... )

  • I think I need to clarify a couple things....

    I could have easily turned the query into a table valued function that I could just call; however, that won't work in this situation. There needs to be a field passed in which will contain the value that needs to be ranked. Here's the rub.

    The data we get is SUPPOSED to have a distinct document number for a series of records/rows in the table. That can be determined by the File Date/Recording date. If there is more than one date per Document, then that's a problem. We can't correct the data as it's not our data to correct. We are strictly forbidden from doing so, by state law, not IT department rules.

    In the case that I get more than one date per document, then I no longer have a unique set of records. OH, a group of records can be, and usually is, a Cartesian product of messy proportions. Thus, I might have a Document Number and File Date Combination on 15 sequential rows of data as there are other bits of data that go along with them than need to be kept together.

    The answer is to create what we call a Unique ID which will Uniquely identify the group. So, DocumentID = 12345 with a File date of 5/21/2014 --my birthday 😛 would have a second File Date of something else, um... 07/09/2014 --wife's birthday :-D. This means I will have to come up with a solution to make the DocumentID unique. So we add a UniqueID field which is a carbon copy of the DocumentID field but with an ought-1 added.. The second record becomes 12345-1. The original solution was U>G>L>Y so I grabbed a ranking function and kibitzed around until I liked the result. It's fast, and the logic is transportable to other databases where the ugliness resides. The problem with that is that my subordinates don't always grasp the higher level stuff like this.... So... If I make it a function, pass in the Unique ID, it will automaticly fix the problem by pumping it through an SSIS/DTSX package... I just suck at writing functions...

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

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