MySQL如何合并3行并计算结果?

时间:2012-02-21 09:49:17

标签: mysql

我目前正在写一个小脚本,从今天早上起我就被困住了。

以下是我的字段:

id | player1 | player2 | player3

示例行:
1 | toto | - | -
2 | tata | toto | -
3 | titi | tutu | -
4 | tata | titi | toto

根据我给出的示例行,我希望能够合并行player1,player2,player3并计算条目数,以得到这样的顶部: 托托3 塔塔2 图图2 titi 1

我经常写基本的查询,所以对于那个,我真的卡住了,现在尝试了几个小时,并且无法得到我想要的东西..任何想法请你好吗?

2 个答案:

答案 0 :(得分:2)

它看起来好像你刚开始做某事,并且你的数据库设计已经非常规范化,这可能会导致性能问题。为了减少这种情况,我建议你在进一步研究之前考虑进行重组。玩家1,玩家2和玩家3都是玩家,因此能够被标准化。您现有表格的每一行都可以被视为game或类似,因此可以进行规范化。然后,您将面临将玩家与游戏联系起来的任务。这样你就不会多次存储相同的玩家细节,并且所有针对表的查询在长期运行中最终会更快,即使初始插入更复杂一些。

players (
    id INT UNSIGNED PK AI,
    name VARCHAR
    .... other player data ....
)

// Assumed a name here
games (
    id INT UNSIGNED PK AI
    .... game data ....
)

// Note the 2-field primary key here.  Prevents 1 player being in the same game twice.
playersInGames (
    game_id INT UNSIGNED PK,
    player_id INT UNSIGNED PK,
    playerNumber TINYINT UNSIGNED  // You don't even need this, if you don't care about player number assigments just don't include this column
)

示例数据

// players
id      name
1       toto
2       tata
3       titi
4       tutu

// games
id
1
2
3
4

// playersInGames
game_id     player_id       playerNumber
1           1               1
2           2               1
2           1               2
3           3               1
3           4               2
4           2               1
4           3               2
4           1               3

这反过来会让您进行简单的查询,例如

SELECT 
    p.*,
    COUNT(DISTINCT pig.game_id) AS gamesPlayerIsIn
FROM players AS p
LEFT JOIN playersInGames AS pig
ON pig.player_id = p.id
GROUP BY p.id

编辑如果您真的不想更改表架构,以下内容就足够了,但会让维护您代码的人感到愤怒。它将每个玩家最多计算一次。

SELECT
    players.playerName,
    COUNT(DISTINCT players.id) AS numberOfRows
FROM (
    (
        SELECT DISTINCT id, player1 AS playerName FROM tableName
    ) UNION DISTINCT (
        SELECT DISTINCT id, player2 AS playerName FROM tableName
    ) UNION DISTINCT (
        SELECT DISTINCT id, player3 AS playerName FROM tableName
    )
) AS players

答案 1 :(得分:0)

select count(*) from ((select id,player1 as players from tablename) union (select id,player2 as players from tablename) union (select id,player3 as players from tablename)) as dummytable group by players

我还没有测试,但看看逻辑:)