January 31, 2006 at 9:10 pm
Here is the first table:
CREATE TABLE "Games"
("ID" int,
"Title" varchar(30),
"Popularity" int)
Here is the second table:
CREATE TABLE "Related"
("ID" int,
"rID" int)
Here is the data for the first table:
INSERT INTO Games (id, title, popularity) VALUES (1, 'Tag Dodgeball', 10)
INSERT INTO Games (id, title, popularity) VALUES (2, 'Freeball', 10)
INSERT INTO Games (id, title, popularity) VALUES (3, 'Doctor Dodgeball', 10)
INSERT INTO Games (id, title, popularity) VALUES (4, 'Kickball', 8)
INSERT INTO Games (id, title, popularity) VALUES (5, 'Fooseball', 8)
INSERT INTO Games (id, title, popularity) VALUES (6, 'Basketball', 7)
INSERT INTO Games (id, title, popularity) VALUES (7, 'Knockout', 6)
Here is the data for the second table:
INSERT INTO Related (ID, rID) VALUES (1,2)
INSERT INTO Related (ID, rID) VALUES (2,1)
INSERT INTO Related (ID, rID) VALUES (1,3)
INSERT INTO Related (ID, rID) VALUES (2,3)
INSERT INTO Related (ID, rID) VALUES (3,1)
INSERT INTO Related (ID, rID) VALUES (3,2)
INSERT INTO Related (ID, rID) VALUES (6,7)
INSERT INTO Related (ID, rID) VALUES (7,6)
Now, lets say a person wants to grab the top three results:
SET ROWCOUNT 3
Select * from Game ORDER BY Popularity
Result Set:
1 Tag Dodgeball 10
2 Freeball 10
3 Dr. Dodgeball 10
But, what if this person doesn't want to play three related games in a row? This is my dilemma. How do I get the following result set:
1 Tag Dodgeball 10
2 Kickball 8
3 Fooseball 8
The related table tells which games are related to which, but how do I get the select statement to realize that it should not select any games that are related once it already has one in the result set?
I can't use distinct, b/c if I do, any games which don't have a relationship are eliminated, as their rID is null.
Pseudo-Code might look something like this:
SET ROWCOUNT 3
Select * from Game ORDER BY Popularity (where ID !=rID)
Please help. I've banging my head against this one for quite some time.
Respectfully,
David.
February 1, 2006 at 2:27 am
Are games always related in groups? In your test data, games 1, 2 and 3 are a group of related games. Similarly for games 6 and 7.
February 1, 2006 at 6:49 am
No, they're not always related. And even if they are related, there might not be any relationship data available for them.
David.
February 1, 2006 at 7:22 am
It's a complicated world...
Try this:
declare @IDs table(Id int)
set rowcount 1
-- execute the same SQL statement 3 times
insert @IDs select id from Games
where id not in
(
select r.rID from @IDs i inner join Related r on i.ID = r.ID
union select id from @IDs
)
order by popularity desc
insert @IDs select id from Games
where id not in
(
select r.rID from @IDs i inner join Related r on i.ID = r.ID
union select id from @IDs
)
order by popularity desc
insert @IDs select id from Games
where id not in
(
select r.rID from @IDs i inner join Related r on i.ID = r.ID
union select id from @IDs
)
order by popularity desc
set rowcount 0
select g.* from Games g inner join @IDs i on g.ID = i.ID
February 1, 2006 at 7:27 am
CREATE TABLE #temp (ID2 int IDENTITY(1,1),[ID] int,Title varchar(30),Popularity int,Related int)
INSERT INTO #temp ([ID],Title,Popularity,Related)
SELECT g.ID,g.Title,g.Popularity,MAX(ISNULL(SIGN(r.rID),0))
FROM Games g
LEFT OUTER JOIN Related r ON r.ID=g.ID
GROUP BY g.ID,g.Title,g.Popularity
ORDER BY g.Popularity DESC
SET ROWCOUNT 3
SELECT t.[ID],t.Title,t.Popularity
FROM #temp t
WHERE NOT EXISTS(SELECT * FROM #temp t2 WHERE t2.ID2 < t.ID2 AND t2.Related > 0 AND t.Related > 0)
ORDER BY t.ID2
DROP TABLE #temp
Far away is close at hand in the images of elsewhere.
Anon.
February 2, 2006 at 2:30 am
I think we read the following differently:
The related table tells which games are related to which, but how do I get the select statement to realize that it should not select any games that are related once it already has one in the result set?
My interpretation was that you cannot select a game that is related to a game that you have already selected. Your interpretation, David B, (correct me if I am wrong ) is that you cannot select a game that is related to another game (no matter which one), except for the first one.
I think we need David M to tell which interpretation is correct. Probably David B's, his ouija board is almost always right
February 2, 2006 at 3:21 am
Yes could be two interpretations
Based on your interpretation
SELECT TOP 3 g.[ID],g.Title,g.Popularity
FROM Games g
WHERE NOT EXISTS(SELECT * FROM Games g2
INNER JOIN Related r2
ON r2.[ID] = g2.[ID] AND r2.[rID] = g.[ID]
WHERE g2.[ID] < g.[ID])
ORDER BY g.[ID] ASC
This assumes the Games table is ordered Popularity DESC with sequential asc ID (as per first post). If the true data in the Games table is not like that then an intermediate temp table will be needed to get sequential ID's.
Far away is close at hand in the images of elsewhere.
Anon.
February 2, 2006 at 4:23 am
Very nice and certainly better than my suggestion
February 2, 2006 at 7:00 am
Thanks for all the suggestions. I am actually looking to include related results but only one result from the related, not both. So I am not looking to exclude the related results entirely.
I haven't had a chance to work with your code samples (this being a nights and weekends project) but will hopefully have some time to do so this Sat. and will let you know how it works. The website it is for is GameSecretary.Com in case you want to see it. Specifically for the Game Generator section (nobody wants to play Tag Dodgeball and Dr. Dodgeball - you want something like Tag Dodgeball and Basketball).
David.
February 3, 2006 at 2:05 am
I realised that there may be a problem with David B's second suggestion. Consider the example below. David B's suggestion returns 1, 4, 5. If my interpretation is correct I think it should be 1, 3, 4. But I don't know if it is possible that 1 is related to 2 and 2 is related to 3, without having 1 related to 3.
I would like to say a little about math. Please jump directly to the code below if you don't feel like reading it...
David M, you should probably ask yourself if the following is true:
If a is related to b then b is related to a.
If a is related to b and b is related to c then a is related to c.
Together with the (rather trivial) condition that a is always related to a, these conditions define what mathematicians call an equivalence relation. Such a relation gives rise to a partition of the objects involved. In your original data set, this would be (1,2,3), (4), (5), (6,7).
Here's the code
CREATE TABLE Games
(ID int,
Title varchar(30),
Popularity int)
go
CREATE TABLE Related
(ID int,
rID int
)
go
INSERT INTO Games (id, title, popularity) VALUES (1, 'Tag Dodgeball', 10)
INSERT INTO Games (id, title, popularity) VALUES (2, 'Freeball', 10)
INSERT INTO Games (id, title, popularity) VALUES (3, 'Doctor Dodgeball', 10)
INSERT INTO Games (id, title, popularity) VALUES (4, 'Kickball', 8)
INSERT INTO Games (id, title, popularity) VALUES (5, 'Fooseball', 8)
INSERT INTO Games (id, title, popularity) VALUES (6, 'Basketball', 7)
INSERT INTO Games (id, title, popularity) VALUES (7, 'Knockout', 6)
INSERT INTO Related (ID, rID) VALUES (1,2)
INSERT INTO Related (ID, rID) VALUES (2,1)
INSERT INTO Related (ID, rID) VALUES (2,3)
INSERT INTO Related (ID, rID) VALUES (3,2)
INSERT INTO Related (ID, rID) VALUES (6,7)
INSERT INTO Related (ID, rID) VALUES (7,6)
February 3, 2006 at 9:58 am
"related" is confusing.
INSERT INTO Related (ID, rID) VALUES (1,2)
INSERT INTO Related (ID, rID) VALUES (2,1)
can tagdodgeball be related to freeball, but freeball not related to tagdodgeball?
can tagdodgeball be related to freeball, and freeball related to kickball, but kickball not related to tagdodgeball?
how are you going to enforce the rules? how do you want your counts presented?
February 3, 2006 at 3:17 pm
If a is related to b, then b will be related to a.
Strictly speaking, if a is related to b and b to c, a is not necessarily related to c. However, the number of times in which a=b=c is not true is very minimal.
David.
February 3, 2006 at 10:49 pm
David's code looks like it will work great. My one problem is that, in fact, the larger data set is not ordered ASC by ID and DESC by Popularity, rather while it is ASC by ID, it is random by Popularity. Can you help me with the intermediary temp table I will need?
David.
February 4, 2006 at 10:56 am
Okay. I think I got it. Here is what the code actually looks like (its a bit more complex than the sample data I originally gave)
If @varAI >0
BEGIN
SET ROWCOUNT @varAI
Insert into #Results
select * FROM Game G
LEFT OUTER JOIN #templastplayed LP
On G.ID=LP.gID2
LEFT JOIN #temppopularity GP
On G.ID=GP.gID
WHERE G.Type=1
AND G.Approved=1
AND (LP.gID2 IS NULL
OR ((LP.LastPlayedDate gp.Popularity2
OR (gp2.Popularity = gp.Popularity2 and g2.ID < g.ID)))
ORDER BY gp.Popularity2 DESC
END
Viewing 14 posts - 1 through 13 (of 13 total)
You must be logged in to reply to this topic. Login to reply