May 9, 2014 at 1:56 pm
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]
May 9, 2014 at 2:30 pm
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/
May 11, 2014 at 11:48 am
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.
May 11, 2014 at 7:49 pm
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
May 11, 2014 at 7:54 pm
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.
May 11, 2014 at 8:08 pm
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... )
May 11, 2014 at 8:23 pm
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