mysql根据条件切换到替代表

时间:2010-08-28 10:50:15

标签: php mysql

这篇文章很长一段时间对不起,但问题也很复杂。

使用mysql和php,
我可以用3个sql请求来解决我的问题,但不能在1中,也不能在2中解决。

这就是我在这里发帖的原因:
你们有没有人知道在不到3招的情况下做到这一点的方法?

(对不起我的英文)

首先让我解释一下背景:
这是关于主题公园!

所以有主题公园老板,
他拥有一个不同区域的主题公园,每个区域都有游戏 根据游戏经理(负责游戏的人),每个游戏可以设置不同的设置。

这是架构的有趣部分是什么样的 有5个表

themeparkzone
--name(varchar)

themeparkzone_has_game_with_manager
--themeparkzone_id(pk)
--game_id(pk)
--manager_id(fk)
--game_settings(text)

themeparkzone_has_game
--themeparkzone_id(pk)
--game_id(pk)
--game_settings(text)

游戏
--name(varchar)

管理器
--name(varchar)

两个表可能需要更多解释:

themeparkzone_has_game_with_manager和themeparkzone_has_game。

如果是themepark所有者,

themeparkzone_has_game可以保留游戏的默认设置 写下他们。

然后themeparkzone_has_game_with_manager保存game_manager已经(或没有)设置的游戏设置,
这些设置应在设置时覆盖themeparkzone_has_game表中的默认设置。

因为主题公园所有者希望他的主题公园非常有吸引力,所以他计划每天更改设置,
以下是他和他的团队必须处理的惯例:

决定适用的游戏设置,

我们在启动时会给出以下变量:
   - manager_id:例如22.
   - 今天的themeparkzone ids,例如12,13,14

所以最终目标是:
对于给定的manager_id,以及给定的themeparkzone_ids,
找出游戏的名称和设置,

鉴于:
如果在themeparkzone_has_game_with_manager中设置了一个设置,它将应用
否则
如果在themeparkzone_has_game中设置了设置,则会应用
否则
没有比赛。

这就是我遇到的问题,
因为我不能在1个请求中做到这一点,
我花了第一个请求来循环themeparkzone_ids,
所以现在的问题是找到给定manager_id和给定themeparkzone_id的游戏名称和设置。

此时,我可以在两个请求中执行此操作,但我想知道是否可以在一个请求中执行此操作。

我的要求是:

SELECT g.name,w.game_settings
  来自游戏g
  INNER JOIN themeparkzone_has_game_with_manager w w.game_id = g.id
  在哪里w.manager_id = 22
  与(12,13,14)

中的w.themeparkzone_id

SELECT g.name,h.game_settings
  来自游戏g
  INNER JOIN themeparkzone_has_game h on h.game_id = g.id
  h .themeparkzone_id在(12,13,14)

首先,我将结果数组放入php数组中然后将它们混合 根据惯例。

所以我想知道是否有一种方法可以解决mysql请求中的条件 而不是用PHP做。

请求会做这样的事情:
foreach(themeparkzone_id和manager_id)
如果在themeparkzone_has_game_with_manager中存在匹配设置 takeit,
否则
如果在themeparkzone_has_game中存在匹配设置 takeit,
否则
takenothing。

希望有人理解我试图解释的内容。

3 个答案:

答案 0 :(得分:2)

考虑到你的数据库布局,我认为改变一些事情可能会更好。

我会将themeparkzone_has_game_with_managerthemeparkzone_has_game_with_manager放在一个表中。然后我会创建一个新表games_managers,建立一个管理员可以管理哪些游戏的连接。

然后我想,应该可以用更少的请求来做。

请注意,您必须自己制定详细信息,即如果需要有经理,您可以为每个游戏指定一个标志等。

答案 1 :(得分:0)

您可以使用LEFT JOINCOALESCE执行此操作。

SELECT
    g.name,
    COALESCE(w.game_settings, h.game_settings)
FROM
    game AS g
    INNER JOIN themeparkzone_has_game AS h ON h.game_id = g.id
    LEFT JOIN themeparkzone_has_game_with_manager AS w ON
        w.game_id = g.id AND
        w.themeparkzone_id = h.themeparkzone_id AND
        w.manager_id = 22
WHERE
    h.themeparkzone_id IN (12, 13, 14)

INNER JOIN不同,即使右侧表中没有与连接条件匹配的行,LEFT JOIN也始终包含左侧表中每行的至少一行。在这种情况下,右侧表格中的列都将为NULLCOALESCE()会返回其提供的第一个非NULL值,因此如果themeparkzone_has_game_with_manager中没有匹配的行,则会返回game_settings中的themeparkzone_has_game值}。

答案 2 :(得分:0)

万岁,
我终于找到了转身,
像我这样的新手有点乱,但它有效,而且...... 只有结果才重要...

以下是符合我需求的请求:
thanx all for your help:

  

选择
      聚结(g.name,g2.name),
      合并(w.params,h.params)
  从
      themeparkzone z
  LEFT JOIN themeparkzone_has_game_with_manager w ON w.themeparkzone_id = z.id AND w.manager_id = 2
  LEFT JOIN themeparkzone_has_game h on h.themeparkzone_id = z.id
  LEFT JOIN游戏g ON g.id = w.game_id
  LEFT JOIN游戏g2 ON g2.id = h.game_id   在(12,13,14)

中的z.id

所以这个请求获取结果在themeparkzone_has_game_with_manager表中, 如果没有创建,请尝试从themeparkzone_has_game获取结果 如果没有建立,仍然返回一个空结果 希望它可以帮到某人。