March 7, 2006 at 1:36 am
Probably an easy one for most of you out there, but my sql is very rusty.
I have a table with two columns -
PRODUCTID, CUSTOMERID
1 4
1 5
2 9
In the above example, I want to return two rows.
PRODUCTID, CUSTOMERID
1 4,5
2 9
The idea is to group by the first column.
Any help appreciated.
March 7, 2006 at 3:29 am
There are a few methods - none of which is that straightforward, but do the job. I've used one method as an example below
Another common method I've seen uses a UDF.
--This SQL script is safe to run
--Create SampleData
DECLARE @SampleData TABLE (PRODUCTID INT, CUSTOMERID INT, CUSTOMERIDS VARCHAR(8000))
INSERT INTO @SampleData (PRODUCTID, CUSTOMERID)
SELECT 1, 4
UNION SELECT 1, 5
UNION SELECT 1, 6
UNION SELECT 2, 9
UNION SELECT 2, 10
UNION SELECT 3, 1
UNION SELECT 3, 5
UNION SELECT 3, 9
UPDATE @SampleData SET CUSTOMERIDS = ''
--Declare and initialise variables
DECLARE @CUSTOMERIDS VARCHAR(8000)
SET @CUSTOMERIDS = ''
DECLARE @PRODUCTID INT
SET @PRODUCTID = ''
--Update CUSTOMERIDS
UPDATE @SampleData SET
@CUSTOMERIDS = CUSTOMERIDS = CASE
WHEN @PRODUCTID = PRODUCTID THEN @CUSTOMERIDS + ', ' + CAST(CUSTOMERID AS VARCHAR(10))
ELSE CAST(CUSTOMERID AS VARCHAR(10)) END,
@PRODUCTID = PRODUCTID
--Select results
SELECT PRODUCTID, MAX(CUSTOMERIDS) AS CUSTOMERIDS
FROM @SampleData
GROUP BY PRODUCTID
Ryan Randall
Solutions are easy. Understanding the problem, now, that's the hard part.
March 7, 2006 at 4:03 am
Genius. Thanks for the help. I just need to display a list of mail recipients on one row in an asp page, so this does the job exactly.
March 7, 2006 at 9:01 am
Since you are using a front end, why not just return the list to the client and concatenate them in the ASP page?
March 8, 2006 at 2:20 am
I decided to use a function.
I will pass in the ID and then cursor through appending to a variable that I will then return from the function.
There's never going to be more than a thousand records so I'm not too concerned about performance.
March 8, 2006 at 2:59 am
Jonathan,
I'd only recommend using a cursor in this situation if you want poor performance and derision from most people on this site
The usual UDF method uses a little trick, as in the example below (and is a very useful trick to know):
--This SQL script creates and drops 2 objects: tblTempSampleData and fnTempGetProductCustomerIds
--Create table: tblTempSampleData
CREATE TABLE tblTempSampleData (PRODUCTID INT, CUSTOMERID INT)
SET NOCOUNT ON
INSERT INTO tblTempSampleData (PRODUCTID, CUSTOMERID)
SELECT 1, 4
UNION SELECT 1, 5
UNION SELECT 1, 6
UNION SELECT 2, 9
UNION SELECT 2, 10
UNION SELECT 3, 1
UNION SELECT 3, 5
UNION SELECT 3, 9
SET NOCOUNT OFF
GO
--Create function: fnTempGetProductCustomerIds
CREATE FUNCTION fnTempGetProductCustomerIds (@PRODUCTID INT) RETURNS VARCHAR(8000) AS
BEGIN
DECLARE @CUSTOMERIDS VARCHAR(8000)
SET @CUSTOMERIDS = ''
--Update CUSTOMERIDS
SELECT
@CUSTOMERIDS = @CUSTOMERIDS + CAST(CUSTOMERID AS VARCHAR(5)) + ', '
FROM
tblTempSampleData
WHERE
PRODUCTID = @PRODUCTID
SET @CUSTOMERIDS = LEFT(@CUSTOMERIDS, LEN(@CUSTOMERIDS) - 1)
RETURN @CUSTOMERIDS
END
GO
--Select the results using the function
SELECT PRODUCTID, dbo.fnTempGetProductCustomerIds(PRODUCTID) AS CUSTOMERIDS
FROM tblTempSampleData GROUP BY PRODUCTID
--Tidy up
DROP TABLE tblTempSampleData
DROP FUNCTION fnTempGetProductCustomerIds
Ryan Randall
Solutions are easy. Understanding the problem, now, that's the hard part.
March 8, 2006 at 7:57 am
Thanks Ryan.
I will give it a go with your scenario.
March 23, 2006 at 4:29 am
I joined the customer table in the function to return a list of customer names rather than IDs and it works perfectly.
I am now able to display an asp page going through 3 different linked tables using the technique.
Thanks again for the help.
March 23, 2006 at 4:45 am
And thanks for the feedback
Ryan Randall
Solutions are easy. Understanding the problem, now, that's the hard part.
Viewing 9 posts - 1 through 8 (of 8 total)
You must be logged in to reply to this topic. Login to reply