一对多搜索查询

时间:2013-09-16 13:30:47

标签: php mysql one-to-many

我有一个MySQL表,我保持一对多的关系。该表用于存储foosball统计程序的合作伙伴列表。玩家可以拥有0,1或2个合作伙伴。

例如:

___________________________________
| Table index | Partners | Players |
|      1      |     1    |  John   | - Singles, no partners
|      2      |     2    |  John   | - Doubles, John and Bob
|      3      |     2    |  Bob    | - Doubles, John and Bob
|      4      |     3    |  Dave   | - Roto doubles, Dave, Bob, John
|      5      |     3    |  Bob    | - Roto doubles, Dave, Bob, John
|      6      |     3    |  John   | - Roto doubles, Dave, Bob, John
|      7      |     4    |  Dave   | - Singles, no partners
____________________________________

我正在编写PHP脚本来从表中添加和检索合作伙伴,我的查询出错了。我知道玩家并想要找回合作伙伴字段。我需要执行三个查询:

  • 检查没有合作伙伴 - 单打;
  • 检查特定合作伙伴 - 双打“戴夫”;
  • 检查两个特定的合作伙伴 - “Bob and Dave”的双打;

如果条目存在,我想检索它,如果没有,那么我会将该条目添加到表中。我遇到的一个麻烦就是例如,玩家“John”有三个条目,没有合作伙伴,一个合作伙伴和两个合作伙伴。如何指定仅拉出条目1而不是2或6?

我在这里搜索过,发现了几个很接近但不完全符合我需要的例子。这个mySQL: Querying one-to-many -table?几乎可以满足我的需求,但并不完全。

非常感谢任何帮助。

克里斯

1 个答案:

答案 0 :(得分:0)

如果我正确理解了您的架构,那么您的Partners字段实际上是隐式分组表中的外键(即,它更好地命名为TeamId并键入名为Team的表,其中每行代表一个伙伴关系)。

让我们定义完整的模式,这样我们就可以正常工作了(这与你的表基本相同,但是非规范化使它更清晰,你也可以使用PlayerId而不是允许不同玩家的名称同名)。这里的多对多连接器表是PlayerTeam。

enter image description here

我们可以通过运行此查询获取TeamId以及给定玩家的团队规模

SELECT TeamId, count(PlayerId) as TeamSize
FROM PlayerTeam
WHERE TeamId IN (SELECT TeamId FROM PlayerTeam WHERE PlayerId = *your-player-id*)
GROUP BY TeamId

您可以通过添加HAVING子句来获得特定规模的团队:

SELECT TeamId, count(PlayerId) as TeamSize
FROM PlayerTeam
WHERE TeamId IN (SELECT TeamId FROM PlayerTeam WHERE PlayerId = *your-player-id*)
GROUP BY TeamId
HAVING TeamSize = 2 

您还可以使用此查询避免每位玩家查询一次:

SELECT p.Name, p.PlayerId, pt.TeamId, sz.TeamSize
FROM Player p JOIN PlayerTeam pt USING(PlayerId)
   JOIN (SELECT TeamId, count(PlayerId) as TeamSize
         FROM PlayerTeam GROUP BY TeamId) AS sz USING(TeamId)

但要有效地使用最后一个,您将希望使用结果来准备一个方便索引的关联数组(如$team[UserId][TeamSize] => TeamId)来做出决策。