Click here to monitor SSC
SQLServerCentral is supported by Red Gate Software Ltd.
 
Log in  ::  Register  ::  Not logged in
 
 
 
        
Home       Members    Calendar    Who's On


Add to briefcase

some UDF FUnction help, please.... Expand / Collapse
Author
Message
Posted Friday, May 9, 2014 1:56 PM


SSC Veteran

SSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC Veteran

Group: General Forum Members
Last Login: Wednesday, October 1, 2014 12:39 PM
Points: 200, Visits: 358
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...


If OBJECT_ID('tempdb..#Crusty_Table') is not null
Begin
Drop table #Crusty_Table
End


Create table #Crusty_Table (
UniqueID varchar(255),
RecordingDate varchar(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

Post #1569440
Posted Friday, May 9, 2014 2:30 PM


SSChampion

SSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampion

Group: General Forum Members
Last Login: Yesterday @ 6:31 PM
Points: 13,207, Visits: 12,688
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 Moden's splitter.

Cross Tabs and Pivots, Part 1 – Converting Rows to Columns
Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs
Understanding and Using APPLY (Part 1)
Understanding and Using APPLY (Part 2)
Post #1569451
Posted Sunday, May 11, 2014 11:48 AM
Valued Member

Valued MemberValued MemberValued MemberValued MemberValued MemberValued MemberValued MemberValued Member

Group: General Forum Members
Last Login: Saturday, November 15, 2014 8:40 AM
Points: 61, Visits: 281
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.

Post #1569644
Posted Sunday, May 11, 2014 7:49 PM


SSC-Insane

SSC-InsaneSSC-InsaneSSC-InsaneSSC-InsaneSSC-InsaneSSC-InsaneSSC-InsaneSSC-InsaneSSC-InsaneSSC-InsaneSSC-Insane

Group: General Forum Members
Last Login: Today @ 1:42 AM
Points: 20,799, Visits: 32,717
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 (
UniqueID varchar(255),
RecordingDate date
)


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





Lynn Pettis

For better assistance in answering your questions, click here
For tips to get better help with Performance Problems, click here
For Running Totals and its variations, click here or when working with partitioned tables
For more about Tally Tables, click here
For more about Cross Tabs and Pivots, click here and here
Managing Transaction Logs

SQL Musings from the Desert Fountain Valley SQL (My Mirror Blog)
Post #1569664
Posted Sunday, May 11, 2014 7:54 PM


SSC-Insane

SSC-InsaneSSC-InsaneSSC-InsaneSSC-InsaneSSC-InsaneSSC-InsaneSSC-InsaneSSC-InsaneSSC-InsaneSSC-InsaneSSC-Insane

Group: General Forum Members
Last Login: Today @ 1:42 AM
Points: 20,799, Visits: 32,717
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 Pettis

For better assistance in answering your questions, click here
For tips to get better help with Performance Problems, click here
For Running Totals and its variations, click here or when working with partitioned tables
For more about Tally Tables, click here
For more about Cross Tabs and Pivots, click here and here
Managing Transaction Logs

SQL Musings from the Desert Fountain Valley SQL (My Mirror Blog)
Post #1569665
Posted Sunday, May 11, 2014 8:08 PM


SSC Veteran

SSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC Veteran

Group: General Forum Members
Last Login: Wednesday, October 1, 2014 12:39 PM
Points: 200, Visits: 358
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... )
Post #1569669
Posted Sunday, May 11, 2014 8:23 PM


SSC Veteran

SSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC Veteran

Group: General Forum Members
Last Login: Wednesday, October 1, 2014 12:39 PM
Points: 200, Visits: 358
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 . 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...


Post #1569672
« Prev Topic | Next Topic »

Add to briefcase

Permissions Expand / Collapse