April 29, 2008 at 7:40 pm
I have a SELECT:
select client.id,service.id
from cliente,service
where cliente.id= service.id_cliente
RESULT
cliente.id service.id
1 10
1 20
2 5
2 1
2 35
3 6
How can I get this RESULT:
cliente.id service.id1 service.id2 service.id3
1 10 20
2 5 1 35
3 6
April 29, 2008 at 8:34 pm
What is the maximum number of ServiceID's you can have per ClientID?
--Jeff Moden
Change is inevitable... Change for the better is not.
April 30, 2008 at 3:11 am
I dont know, Its dynamic...
Could be 3-4-5-6... 🙁
April 30, 2008 at 6:32 am
Dynamic is gonna cause the problem there......maybe someone else knows a way of doing a SELECT statement with a dynamic number of Select fields but I've never come across one.
Here's an alternative....this function is designed to create a comma delimited list of all last names for each first name from an Employees table:
CREATE FUNCTION dbo.TMP_FX_LASTNAMES(@firstName varchar(100),@lastNameList varchar(600),@count int) RETURNS varchar(600)
BEGIN
DECLARE @newName varchar(100)
IF @count = 32
BEGIN
return 'Maximum number of names reached'
END
ELSE
BEGIN
IF Exists(SELECT RTRIM(LASTNAME) FROM EMPLOYEES WHERE RTRIM(FIRSTNAME) = @firstName AND CHARINDEX(RTRIM(LASTNAME),@lastNameList) = 0)
BEGIN
SELECT TOP 1 @newName = RTRIM(LASTNAME) FROM EMPLOYEES WHERE RTRIM(FIRSTNAME) = @firstName AND CHARINDEX(RTRIM(LASTNAME),@lastNameList) = 0
IF @lastNameList = ''
BEGIN
SET @lastNameList = @newName
END
ELSE
BEGIN
SET @lastNameList = @lastNameList + ', ' + @newName
END
SET @lastNameList = dbo.TMP_FX_LASTNAMES(@firstName,@lastNameList,(@count+1))
END
return @lastNameList
END
return ''
END
I know it's not exactly what you are looking for but if you're eventually going to be using the result of the query within something like ASP or .NET or some other language, there's a chance that you could turn the second column into an array, add one column and put your ID in there and then you have what you need.
April 30, 2008 at 8:38 am
Bruna (4/30/2008)
I dont know, Its dynamic...Could be 3-4-5-6... 🙁
Putts (4/30/2008)
Dynamic is gonna cause the problem there......maybe someone else knows a way of doing a SELECT statement with a dynamic number of Select fields but I've never come across one.
Heh... now you have... 😀
--===== Do a little setup to make the message window pretty
SET NOCOUNT ON
SET ANSI_WARNINGS OFF
--===== Create and populate a demonstration table
DECLARE @DemoTable TABLE
([cliente.id] INT, [service.id] INT)
INSERT INTO @DemoTable
([cliente.id],[service.id])
SELECT 1,10 UNION ALL
SELECT 1,20 UNION ALL
SELECT 2,5 UNION ALL
SELECT 2,1 UNION ALL
SELECT 2,35 UNION ALL
SELECT 3,6
--===== Declare a variables to hold dynamic SQL
DECLARE @SQL1 VARCHAR(MAX)
DECLARE @SQL2 VARCHAR(MAX)
DECLARE @SQL3 VARCHAR(MAX)
DECLARE @MyRankMax INT
--===== Build a working table with raning for each row
SELECT MyRank = ROW_NUMBER() OVER (PARTITION BY [cliente.id]
ORDER BY [cliente.id],[service.id]),
[cliente.id],
[service.id]
INTO #MyWork
FROM @DemoTable
--===== Remember the largest rank to limit the number of columns
SELECT @MyRankMax = MAX(MyRank) FROM #MyWork
--===== Build the dynamic SQL in it's component parts
SELECT @SQL1 = 'SELECT [cliente.id],'+CHAR(10)
SELECT @SQL2 = COALESCE(@SQL2+','+CHAR(10),'')
+ 'MAX(CASE WHEN MyRank = '+LTRIM(STR(N))
+ ' THEN [service.id] ELSE NULL END) AS [Service.ID'
+ LTRIM(STR(N))+']'
FROM dbo.Tally
WHERE N <= @MyRankMax
SELECT @SQL3 = CHAR(10)+'FROM #MyWork GROUP BY [cliente.id] ORDER BY [cliente.id]'
--===== Print what the dynamic SQL looks like (Cross-tab)
-- This can be commented out for production
PRINT @SQL1+@SQL2+@SQL3
--===== Execute the dynamic SQL to get a single return
EXEC (@SQL1+@SQL2+@SQL3)
--===== Housekeeping for reruns of the test
DROP TABLE #MyWork
And, if you don't already have the wonderfully useful utility table known as a "Tally" table, please visit the following URL for how to make one...
http://www.sqlservercentral.com/scripts/Advanced+SQL/62486/
--Jeff Moden
Change is inevitable... Change for the better is not.
April 30, 2008 at 8:48 am
Yeah.....I thought about a stored proc to creat a temp table and go that route but I actually liked the concept of having a more structured output.
I'm always looking at this from a Software Developer aspect than I am a Database Developer viewpoint so from that stance I was trying to provide a way that he'd be able always know guaranteed where the data would be. With the function, the data he'd need would always be in the second column which might make it easier to code around.
Not even sure what he's using it for but now he should know a couple ways of doing it 😛
April 30, 2008 at 9:07 am
Yeah... I agree... if it's a return to the GUI, the comma separated list would probably be the way to go for the very reasons you stated. Thanks...
--Jeff Moden
Change is inevitable... Change for the better is not.
Viewing 7 posts - 1 through 6 (of 6 total)
You must be logged in to reply to this topic. Login to reply