我有一个包含1500多个在线游戏数据的SQL表。每个游戏都有描述它们的标签(每个游戏有1到5个标签)。例如,this game在重要级别中具有以下标签“Dirt Bike”,“Racing”,“Stunts”,“Trial”,“Mountain”。对于每个游戏,我想选择最相关的12个游戏。
我正考虑给每个标签赋予“重要性”权重。
标签1 = 5分
标签2 = 4分
标签3 = 3分
标签4 = 2分
标签5 = 1 pt
并乘以匹配的标签。因此,如果另一个游戏是关于“汽车”,“赛车”,“山”,它将得到:0 +(4 x 4)+(3 x 1)= 19pts。然后我会比较所有比赛的结果并显示12分最多的分数。
我知道如何使用PHP对数学比较部分进行编码,但在仅显示前12个游戏之前,不知道如何有效地存储部分结果(即每个1500的比较点)。我应该创建一个表来存储临时1500结果吗?或者有没有办法将这些结果存储在内存中,然后只抓住前12个?
注意:我可能会将最终结果存储在一个1500x12的SQL表中,并且只在我每天大约一次添加新游戏时运行比较。
答案 0 :(得分:2)
虽然这个问题应该被视为过于宽泛而不适合在这里(请在问之前先尝试一下!),但我很乐意回答它。
我不会在PHP中这样做,而是在纯SQL中。
假设这样的结构:
CREATE TABLE game (
game_id INT PRIMARY KEY,
name VARCHAR(50)
);
CREATE TABLE tag (
tag_id INT PRIMARY KEY,
label VARCHAR (50)
);
CREATE TABLE gametag (
game_id INT,
tag_id INT,
rank INT, -- ranks from 1 to 5, rank "1" will weightmeans "5 points"
PRIMARY KEY (game_id, tag_id),
UNIQUE (game_id, tag_id, rank),
CONSTRAINT gid_fk FOREIGN KEY gid_fk_idx (game_id) REFERENCES game (game_id),
CONSTRAINT tid_fk FOREIGN KEY tid_fk_idx (tag_id) REFERENCES tag (tag_id)
);
两个游戏之间的“匹配分数”将通过以下查询获得:
SELECT
game1.name AS game_1,
game2.name AS game_2,
SUM(match_score) AS score
FROM (
SELECT
game1.game_id AS game1_id,
game2.game_id AS game2_id,
(6 - gametag1.rank) * (6 - gametag2.rank) AS match_score -- modify the magic "6" if you allow more or less than 5 tags
FROM game AS game1
JOIN gametag AS gametag1 USING (game_id)
JOIN tag AS tag1 USING (tag_id)
JOIN tag AS tag2 USING (tag_id)
JOIN gametag AS gametag2 USING (tag_id)
JOIN game AS game2 ON game2.game_id = gametag2.game_id
WHERE game1.game_id = 1 AND game2.game_id = 2
) AS scores
JOIN game AS game1 ON game1.game_id = game1_id
JOIN game AS game2 ON game2.game_id = game2_id
GROUP BY game1_id, game2_id;
答案 1 :(得分:0)
继承了一些SQL,也许这会起作用?:
SELECT g.id AS game_id, g.game AS game_name, SUM(t.tag_points) AS tag_points
FROM games g
INNER JOIN game_tags gt
ON gt.game_id = g.id
INNER JOIN tags t
ON t.id = gt.tag_id
GROUP BY gt.game_id
ORDER BY tag_points DESC
您需要一个类似于此的表结构:
Table: games
+----+-------------+
| id | game |
+----+-------------+
| 1 | Test Game 1 |
| 2 | Test Game 2 |
+----+-------------+
Table: tags
+----+------------+------------+
| id | tag_name | tag_points |
+----+------------+------------+
| 1 | test tag 1 | 1 |
| 2 | test tag 2 | 2 |
+----+------------+------------+
Table: game_tags
+----+---------+--------+
| id | game_id | tag_id |
+----+---------+--------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 2 | 2 |
+----+---------+--------+
答案 2 :(得分:0)
表tags
id | name |
------------------
1 | cars |
2 | rpg |
3 | shooter |
4 | mountain |
5 | fps |
6 | trial |
7 | racing |
8 | .... |
9 | .... |
表games
id | name |
------------------
1 | race_game |
2 | shoot_game |
表game_tags
id | game_id | first_tag | second_tag | third_tag | fourth_tag | fifth_tag |
-----------------------------------------------------------------------------
1 | 1 | 7 | 1 | 4 | 2 | 6 |
2 | 2 | 5 | 8 | 3 | 2 | 9 |
所以你可以多次LEFT JOIN game_tags来比较第一次连接的标签等于第二次连接的位置,依此类推。 LEFT JOIN会在非匹配值上给出NULL结果,因此只有matchable才会有tag_id。根据匹配的标签,您可以给出积分。例如,如果匹配从第四个标记开始,您将给出fourth_tag的分数,据我所知,first_tag匹配提供更多分数,并随着标记的等级而减少。