NoCoolHandle
Programmer
I bumped into a new one for me the other day that I thought I would share..
Imagine 2 tables (Family and firstnames)
Each Family can only have one LastName, but each Family could have more than one firstname (representing differ the different family members)
I.E. A Family of Smith with 4 members could be represeted a couple of ways
LastName FamilyMembers
Smith John, Mary, Jane, Jill
Or
LastName FirstName
Smith John
Smith Mary
Smith Jane
Smith Jill
In the case of display simplicity the first option is cleaner, but sql really wants you to see the second option.
So...
The solution might be to bulid a cursor (as in ) and 1 row at a time append the new firstname to the last FirstName with a comma stuck between, but that is intensive.. and bottom line - CURSORS have no place in efficent SQL period (IMHO)
Here is what I found would work (full scripts for you to play with at the bottom) - remember I HATE cursors.. they just arn't necessary and place locks on resources like they are going out of fasion.
1 row - displayed with commas between each family member
The interesting thing is that setting the variable to being equal to itself + the column value causes it to process the entire rowset.
Select [blue]@v[/blue] = [blue]@v + Firstname + ', '[/blue] From Firstnames
would return something like
John, Mary, Jane, Jill,
The question becomes how do you make the variable work for each Family rather than 1 member at a time.. (step in the UDF)
Then to use it just pass in the memberID
e.g.
For what it is worth...
I just thought it interesting and can't rember seeing it written up anywhere.
Imagine 2 tables (Family and firstnames)
Each Family can only have one LastName, but each Family could have more than one firstname (representing differ the different family members)
I.E. A Family of Smith with 4 members could be represeted a couple of ways
LastName FamilyMembers
Smith John, Mary, Jane, Jill
Or
LastName FirstName
Smith John
Smith Mary
Smith Jane
Smith Jill
In the case of display simplicity the first option is cleaner, but sql really wants you to see the second option.
So...
The solution might be to bulid a cursor (as in ) and 1 row at a time append the new firstname to the last FirstName with a comma stuck between, but that is intensive.. and bottom line - CURSORS have no place in efficent SQL period (IMHO)
Here is what I found would work (full scripts for you to play with at the bottom) - remember I HATE cursors.. they just arn't necessary and place locks on resources like they are going out of fasion.
1 row - displayed with commas between each family member
Code:
Declare @v varchar(8000)
Select @v=''
Select @v = @v + Firstname + ', ' From Firstnames where mid = 1
select Left(@v,Len(@v)-1)
The interesting thing is that setting the variable to being equal to itself + the column value causes it to process the entire rowset.
Select [blue]@v[/blue] = [blue]@v + Firstname + ', '[/blue] From Firstnames
would return something like
John, Mary, Jane, Jill,
The question becomes how do you make the variable work for each Family rather than 1 member at a time.. (step in the UDF)
Code:
Create Function fn_ReturnFamilyMembers
(@Mid int)
Returns Varchar(8000)
as
begin
Declare @v varchar(8000)
Select @v=''
Select @v = @v + Firstname + ', '
From Firstnames where
mid = @mid
select @v= Left(@v,Len(@v)-1)
Return @v
End
e.g.
Code:
Select Mid,LastName,dbo.fn_ReturnFamilyMembers(mid) as Members
From Familys
Order by LastName
[code]
Would return something like
[Quote]
Mid lastname Members
----------- ---------- ------------------------------
9 Apple Granny
5 Cruz Solo
4 Dao PIede, Dinggone
8 Dooshee Baghe, Quick
2 Jones Sally, Rafiel, Sierra
7 O'Guin Paddy
3 Patel Tom, Sky, Moon
1 Smith Bob, Mary, Tom, Jim, Emily
6 Stoner Duice1, Duice2
10 Xaolin Zeta, Beta, Alpha
[/Quote]
FULL SCRIPTS _ CUT AN PASTE INTO QA
[Code]
Create database Crap
go
Use Crap
go
create table Familys
(mid int identity primary key,
LastName varchar(300) not null)
create table firstnames
(mid int foreign key references Familys(mid),
FirstName varchar(300))
go
Insert into Familys (lastname) values('Smith')
insert into FirstNames (Mid,Firstname) values (1,'Bob')
insert into FirstNames (Mid,Firstname) values (1,'Mary')
insert into FirstNames (Mid,Firstname) values (1,'Tom')
insert into FirstNames (Mid,Firstname) values (1,'Jim')
insert into FirstNames (Mid,Firstname) values (1,'Emily')
Insert into Familys (lastname) values('Jones')
insert into FirstNames (Mid,Firstname) values (2,'Sally')
insert into FirstNames (Mid,Firstname) values (2,'Rafiel')
insert into FirstNames (Mid,Firstname) values (2,'Sierra')
Insert into Familys (lastname) values('Patel')
insert into FirstNames (Mid,Firstname) values (3,'Tom')
insert into FirstNames (Mid,Firstname) values (3,'Sky')
insert into FirstNames (Mid,Firstname) values (3,'Moon')
Insert into Familys (lastname) values('Dao')
insert into FirstNames (Mid,Firstname) values (4,'PIede')
insert into FirstNames (Mid,Firstname) values (4,'Dinggone')
Insert into Familys (lastname) values('Cruz')
insert into FirstNames (Mid,Firstname) values (5,'Solo')
Insert into Familys (lastname) values('Stoner')
insert into FirstNames (Mid,Firstname) values (6,'Duice1')
insert into FirstNames (Mid,Firstname) values (6,'Duice2')
Insert into Familys (lastname) values('O''Guin')
insert into FirstNames (Mid,Firstname) values (7,'Paddy')
Insert into Familys (lastname) values('Dooshee')
insert into FirstNames (Mid,Firstname) values (8,'Baghe')
insert into FirstNames (Mid,Firstname) values (8,'Quick')
Insert into Familys (lastname) values('Apple')
insert into FirstNames (Mid,Firstname) values (9,'Granny')
Insert into Familys (lastname) values('Xaolin')
insert into FirstNames (Mid,Firstname) values (10,'Zeta')
insert into FirstNames (Mid,Firstname) values (10,'Beta')
insert into FirstNames (Mid,Firstname) values (10,'Alpha')
select M.*,firstname from Familys M left outer join FirstNames F on M.mid = f.mid
Declare @v varchar(8000)
Select @v=''
Select @v = @v + Firstname + ', ' From Firstnames where mid = 1
select Left(@v,Len(@v)-1)
go
Create Function fn_ReturnFamilyMembers
(@Mid int)
Returns Varchar(8000)
as
begin
Declare @v varchar(8000)
Select @v=''
Select @v = @v + Firstname + ', '
From Firstnames where
mid = @mid
select @v= Left(@v,Len(@v)-1)
Return @v
end
go
Select Mid,LastName,dbo.fn_ReturnFamilyMembers(mid)as Members
From Familys
Order by LastName
go
drop table firstnames
drop table familys
drop function fn_ReturnFamilyMembers
For what it is worth...
I just thought it interesting and can't rember seeing it written up anywhere.