MySQL数据比较

时间:2013-06-05 15:54:48

标签: php mysql

我有一个包含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表中,并且只在我每天大约一次添加新游戏时运行比较。

3 个答案:

答案 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匹配提供更多分数,并随着标记的等级而减少。