Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 similar to split function

Author  Topic 

dreamaboutnothing
Starting Member

47 Posts

Posted - 2004-10-06 : 14:25:20
Hi,
I have one field like detail_name_id with a datatype as ntext.I need to find out which id is most popular one but i don't know how to split these 78764 78758 78758.Is there any function which can split these values.Thank you in advance

78770
78762
78764 78758 78758
78779
78769
0
0

spirit1
Cybernetic Yak Master

11752 Posts

Posted - 2004-10-06 : 14:33:38
of course there is:


CREATE FUNCTION dbo.Split
(
@RowData nvarchar(2000),
@SplitOn nvarchar(5)
)
RETURNS @RtnValue table
(
Id int identity(1,1),
Data nvarchar(100)
)
AS
BEGIN
While (Charindex ( @SplitOn,@RowData)>0)
Begin
Insert Into @RtnValue (data)
Select
Data = ltrim(rtrim(Substring( @RowData,1,Charindex ( @SplitOn,@RowData)-1)))

Set @RowData = Substring( @RowData,Charindex ( @SplitOn,@RowData)+1,len( @RowData))
End

Insert Into @RtnValue (data)
Select Data = ltrim(rtrim(@RowData))
Return
END


Go with the flow & have fun! Else fight the flow
Go to Top of Page

dreamaboutnothing
Starting Member

47 Posts

Posted - 2004-10-06 : 14:58:52
HI,
Thank you so much!You know what? Actually i am trying to find the most popular id's for two fields i was able to do one with the following statement since there were no multiple values in any column
select dir_category_id FROM
(select top 1 dir_category_id, number=count(dir_category_id) from DI_webclick_statistics
where dir_category_id <>'0'
group by dir_category_id order by number desc)dt ;
My output is 51

Right now for this field since there are multiple values in one field only and i am not able to do it using the above mentioned statement.
Sorry, the function you wrote, didn't give me what i want.Any other way you think that i can split these values and find out which one is most popular one. Thanks
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2004-10-06 : 15:00:39
do not store your data in this format. is this a database you have designed? Can you change the structure? never store more than 1 value in a single column. (You have already learned why !)

- Jeff
Go to Top of Page

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2004-10-06 : 15:03:39
how bout the following...


--Declare @numbers table (n int)
--Insert Into @numbers
--Select n = number from dbo.getsequence(0,1000,1)

Declare @numbers table (n int identity(0,1), blah int)
Insert Into @numbers
Select 0 from master.dbo.syscolumns

Declare @myTable table (id int identity(1,1), myVal varchar(1000))
Insert Into @myTable
Select '78770'
Union Select '78762'
Union Select '78764 78758 78758'
Union Select '78779'
Union Select '78769'
Union Select '0'
Union Select '0'

Declare @split table (id int, myVal varchar(1000), posA int, posB int, splitVal varchar(100))

Insert Into @split
Select
id,
myVal,
posA,
posB = min(posB),
splitVal = rtrim(ltrim(substring(myVal,posA,isnull(min(posB),len(myVal))-posA+1)))
From
(
Select A.id, A.myVal, posA = B.n, posB = C.n
From @myTable A
Inner Join (Select * From @numbers Where n between 0 and (Select max(len(myVal)) From @myTable)) B
On Substring(A.myVal,B.n,1)=' '
and len(rtrim(ltrim(A.myVal)))>=B.n
Left Join (Select * From @numbers Where n between 0 and (Select max(len(myVal)) From @myTable)) C
On B.n+1<=C.n
and Substring(A.myVal,C.n,1)=' '
and len(rtrim(ltrim(A.myVal)))>=C.n
) Z
Group by id, myVal, posA

Select splitVal, count(*)
From @split
Group By splitVal
Order By 2 desc, 1


Corey
Go to Top of Page

spirit1
Cybernetic Yak Master

11752 Posts

Posted - 2004-10-06 : 15:16:15
corey... i really think this is a bit of overkill
but hey if it works...

Go with the flow & have fun! Else fight the flow
Go to Top of Page

dreamaboutnothing
Starting Member

47 Posts

Posted - 2004-10-06 : 15:42:52
Hi Guys
Thank You so much! Corey, it did work.It looked so complicated. I really need to go through this and see how did it work.My statement looks so simple and your looks so complicated but bottomline is i got the result what i wanted. Thanks
Go to Top of Page

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2004-10-06 : 15:49:35
quote:
Originally posted by spirit1

corey... i really think this is a bit of overkill
but hey if it works...

Go with the flow & have fun! Else fight the flow



Yeah it probably is overkill... BUT it does do a split on a column without a loop. I finally realized how to do that. I'm sure someone else has done something similar around here, but it seems like it would be easier to implement once I'm used to the logic.

Corey
Go to Top of Page

spirit1
Cybernetic Yak Master

11752 Posts

Posted - 2004-10-06 : 15:54:59
don't get me wrong. i think it's cool.

Go with the flow & have fun! Else fight the flow
Go to Top of Page

dreamaboutnothing
Starting Member

47 Posts

Posted - 2004-10-06 : 16:03:11
Hi Guys,
If you come up with something simple i would really appreciate it.I really don't want to memorize this and to be very honest i am still trying to understand how did it work.I just wanted a simple nested select statement the way i used to get the same result but without split function.For the time being Corey i will be using your code but would still prefer something simpler. Thanks
Go to Top of Page

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2004-10-06 : 16:26:25
the problem with splitting a column, is that you are in essence trying to generate one or more records from a given records column data.

if you are looking at a single value (set of values) and splitting that the multiple records are not a problem, but when looking at the column values of (column of sets), creation of the records will require one of the following:

1-Looping action to process the set 1 'unit' at a time
2-A set based statement that utilizes joins to create the additional records where provided


Declare @split table (id int, myVal varchar(1000), posA int, posB int, splitVal varchar(100))

Insert Into @split
--group by id, myVal, posA to get the least posB > than posA, and do substring calculation
Select
id,
myVal,
posA,
posB = min(posB),
splitVal = rtrim(ltrim(substring(myVal,posA,isnull(min(posB),len(myVal))-posA+1)))
From
(
Select A.id, A.myVal, posA = B.n, posB = C.n
From @myTable A
--use only the numbers that are less than or equal to the length of the longest set
Inner Join (Select * From @numbers Where n between 0 and (Select max(len(myVal)) From @myTable)) B
--join where the delimiter is at the position of n from the numbers table
On Substring(A.myVal,B.n,1)=' '
and len(rtrim(ltrim(A.myVal)))>=B.n
--use only the numbers that are less than or equal to the length of the longest set
Left Join (Select * From @numbers Where n between 0 and (Select max(len(myVal)) From @myTable)) C
--join where the delimiter is at the position of n from the numbers table
--and greater than the n from the first numbers table

On B.n+1<=C.n
and Substring(A.myVal,C.n,1)=' '
and len(rtrim(ltrim(A.myVal)))>=C.n
) Z
Group by id, myVal, posA

Select splitVal, count(*)
From @split
Group By splitVal
Order By 2 desc, 1



Corey
Go to Top of Page

dreamaboutnothing
Starting Member

47 Posts

Posted - 2004-10-06 : 16:35:11
Thanks Corey for explaining it. I appreciate it.
Go to Top of Page
   

- Advertisement -