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
 SQL Server Development (2000)
 Another Random Challenge

Author  Topic 

Johnhamman
Starting Member

37 Posts

Posted - 2002-10-09 : 17:47:28
Ok folks, Help me out please.
I have table that contains multiple products from different categories. Categories are defined by the cID field. Product Ids are defined by the pID field and i have a identiy field called idNum.
Now what i would like to do is pull back one RANDOM product for each category. The amount of products and the amount of categories that may be in this table may change at any time. Sometimes there may be 7 categories and other times only 3 category that the products are under.
Can someone help me on this. I have tried everything and am not able to get anywhere. I tried grouping but dont know how to get a random product.I am so frustrated on this.
-John

ValterBorges
Master Smack Fu Yak Hacker

1429 Posts

Posted - 2002-10-09 : 17:54:00
Take a look at
http://www.sqlteam.com/item.asp?ItemID=896
http://www.sqlteam.com/item.asp?ItemID=802

You can usually try the search on the main page or search the forums for similar problems.



Edited by - ValterBorges on 10/09/2002 17:55:36
Go to Top of Page

Johnhamman
Starting Member

37 Posts

Posted - 2002-10-09 : 18:09:26
thanks, I had tried that method but still am haveing problems with the fact that it pulls back random products but not distict categories. I did forget to mention that the one advantage to this table is that there is no gaps in the identities.


temptable1
idNum int identity(1,1),
pId int, --this is the product id
cId int -- this is the category id

in this table there may be 72 products under about 5 distict categories.
what i cant figure out is how to pull a random product for each category. so if there is 3 categories that the products are under then show one random product that falls under that one category for each category.
I can get it to pull back random products but not random for each category.




Go to Top of Page

Lavos
Posting Yak Master

200 Posts

Posted - 2002-10-10 : 01:43:30
Weeeeell, it depends. If the categories are permanent (HAH) then you could create a view for each category, and then pull a random row from each view. An exension would be to write a stored procedure that used dynamic sql to do this. I don't recomend it.


Another approach is to use a while loop to get one row at a time, and insert them into a temp table. You then only look at products that have a category that isn't in your temp table.

I honestly don't remember all the rules for RAND in SQL Server, so this probably won't work right, and I definately haven't ran it. YMMV


CREATE #TempTable (
RowID int,
CatID in
)

DECLARE @MinRow int
DECLARE @MaxRow int
DECLARE @RanRow int

SELECT @MinRow = MIN(ProductID), @MaxRow = MAX(ProductID)
FROM Products

WHILE EXISTS(SELECT * FROM Products WHERE CatID NOT IN (SELECT CatID FROM #TempTable))
BEGIN
SET @RanRow = ROUND(RAND()*(@MaxRow - @MinRow), 0) + @MinRow

-- This is done to remove a bias. Note that technically this could
-- repeat forever, but only theoretically. Highly inefficient, find
-- a different way if you can :)
WHILE NOT EXISTS(SELECT * FROM Products WHERE CatID NOT IN (SELECT CatID FROM #TempTable))
BEGIN
SET @RanRow = ROUND(RAND()*(@MaxRow - @MinRow), 0) + @MinRow
END

INSERT #TempTable
SELECT ProductID, CatID FROM Products WHERE RowID = @RanID

SELECT @MinRow = MIN(ProductID), @MaxRow(ProductID) FROM Products
WHERE CatID NOT IN (SELECT CatID FROM #TempTable)

END

-- Okay, then you can join them to return full details
SELECT Products.*
FROM Products INNER JOIN #TempTable ON (ProductID = RowID)



----------------------
"O Theos mou! Echo ten labrida en te mou kephale!"

<Edited to remove a couple of syntax errors in code. blah>

Edited by - Lavos on 10/10/2002 01:45:20
Go to Top of Page

Arnold Fribble
Yak-finder General

1961 Posts

Posted - 2002-10-10 : 15:47:21
If you're willing to consider the idea of sorting on NEWID:
see: http://www.sqlteam.com/item.asp?ItemID=8747
but see Jasper Smith's well-placed warnings in this thread: http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=20430

About 500 rows of test data:

CREATE TABLE ProductCategories (
productID int NOT NULL,
categoryID int NOT NULL,
PRIMARY KEY (productID, categoryID)
)

DECLARE @p int, @c int

SET NOCOUNT ON
BEGIN TRANSACTION

SET @p = 0
WHILE @p < 100
BEGIN
SET @c = 0
WHILE @c < 10
BEGIN
IF RAND() < 0.5
INSERT INTO ProductCategories VALUES (@p, @c)
SET @c = @c + 1
END
SET @p = @p + 1
END

COMMIT TRANSACTION
SET NOCOUNT OFF

 
This probably doesn't scale well, but it's fine for 500 rows:

SELECT * FROM ProductCategories AS T1
WHERE categoryID = (
SELECT TOP 1 categoryID
FROM ProductCategories AS T2
WHERE T1.productID = T2.productID
ORDER BY NEWID()
)



Edited by - Arnold Fribble on 10/10/2002 15:50:34
Go to Top of Page

Johnhamman
Starting Member

37 Posts

Posted - 2002-10-15 : 17:22:37
I appreciate the help all, but unfortunatly i couldnt get either examples to work. Could anyone help a little more?

To recap. I'm trying to pull back one random product from a products table for each sub category from a category table. The main category is sent from the asp page.
thanks
john

Go to Top of Page
   

- Advertisement -