加入表格mysql-无需两次迭代

时间:2018-06-24 06:16:15

标签: php mysql sql database database-design

首先让我说这应该是一个相对简单的问题,由于数据库设计不佳(不是我本人),使/变得不必要,这也使我也不是mysql专家。

请考虑以下内容

餐桌时间表

enter image description here

请注意homeIDvisitorID列是如何包含团队名称而不是实际teamID的

为解决此问题,我创建了一个新表,其中的列包含teamIDteamName,如下图所示。

桌队

enter image description here

我的问题

我必须从table Teams获取主队和客队的teamID

所以我创建了Teams表和这个简单的脚本:

SELECT schedule.*, teams.* FROM schedule JOIN teams ON schedule.homeID = teams.teamName OR schedule.visitorID = teams.teamName WHERE schedule.gameID = 411 LIMIT 1 #added Limit1 else the code generates to rows

mysql脚本的输出

限制1

enter image description here

关于以上如何仅使用Limit 1

为1个团队生成的teamID的通知

无限制声明(双重迭代)

enter image description here

以上注意事项,如何为两个团队都获取teamID。 问题是它进行了两次迭代。

TLDR;上面提出了以下问题

  1. 首先,脚本将生成两个输出,一个输出给主队,一个输出给客队。可以预料,但是我不能拥有它。

  2. 作为第1个问题的解决方法-我添加了Limit 1Limit带来的问题是,尽管它只返回一个teamID(据预期,我猜)

问题

如何通过一次迭代从表团队中获得两个teamID?希望这有道理....

额外

带有硬编码团队名称的应用程序演示如下(只是为了说明他们要实现的目标)

enter image description here

3 个答案:

答案 0 :(得分:2)

您想将teams两次加入schedule的声音。

SELECT s.*,
       th.*,
       ta.*
       FROM schedule s
            INNER JOIN teams th
                       ON s.homeid = th.teamname
            INNER JOIN teams ta
                       ON s.visitorid = ta.teamname 
       WHERE s.gameid = 411;

答案 1 :(得分:2)

我想您想将两个团队显示为一行而不是两行。
如果是,那么您需要两次连接表teams

考虑这个演示:http://www.sqlfiddle.com/#!9/bb5e61/1

此次加入会将两支队伍聚集到一排:

SELECT s.*,
       t1.teamId as homeId_teamId,
       t1.teamCode as homeId_teamCode,
       t1.teamName as homeId_teamName,
       t2.teamId as visitorId_teamId,
       t2.teamCode as visitorId_teamCode,
       t2.teamName as visitorId_teamName      
FROM Schedule s
JOIN Teams t1 ON s.homeId = t1.teamName
JOIN Teams t2 ON s.visitorId = t2.teamName;

| id | homeId | visitorId | homeId_teamId | homeId_teamCode | homeId_teamName | visitorId_teamId | visitorId_teamCode | visitorId_teamName |
|----|--------|-----------|---------------|-----------------|-----------------|------------------|--------------------|--------------------|
|  1 | Poland |  Colombia |             1 |              PL |          Poland |                2 |                 CO |           Colombia |

但是,您也可以考虑在INNER联接上使用LEFT联接,这在TEAMS表中没有相关数据的情况下将起作用:

SELECT s.*,
       t1.teamId as homeId_teamId,
       t1.teamCode as homeId_teamCode,
       t1.teamName as homeId_teamName,
       t2.teamId as visitorId_teamId,
       t2.teamCode as visitorId_teamCode,
       t2.teamName as visitorId_teamName      
FROM Schedule s
LEFT JOIN Teams t1 ON s.homeId = t1.teamName
LEFT JOIN Teams t2 ON s.visitorId = t2.teamName;

| id |   homeId | visitorId | homeId_teamId | homeId_teamCode | homeId_teamName | visitorId_teamId | visitorId_teamCode | visitorId_teamName |
|----|----------|-----------|---------------|-----------------|-----------------|------------------|--------------------|--------------------|
|  1 |   Poland |  Colombia |             1 |              PL |          Poland |                2 |                 CO |           Colombia |
|  3 | Ya Majka |    Poland |        (null) |          (null) |          (null) |                1 |                 PL |             Poland |
|  2 | Ya Majka |   Rossija |        (null) |          (null) |          (null) |           (null) |             (null) |             (null) |

以下是构成示例表格的脚本

CREATE TABLE Schedule(
  id int,   homeId varchar(20),visitorId varchar(20)
);

INSERT INTO Schedule VALUES
(1, 'Poland', 'Colombia' ),(2,'Ya Majka','Rossija'), 
(3,'Ya Majka','Poland');

CREATE TABLE Teams( 
  teamId int, teamCode varchar(10), teamName varchar(20)
);

INSERT INTO Teams VALUES
(1, 'PL', 'Poland' ),(2,'CO','Colombia'),(3,'US','United States');

答案 2 :(得分:2)

您可以使用子查询(在同一查询中两个)来解决此问题:

select
  gameID, 
  weekNum,
  gameTimeEastern,
  (select teamName from teams where teamID = schedule.homeID) as homeName,
  homeScore,
  (select teamName from teams where teamID = schedule.visitorID) as visitorName,
  visitorScore from schedule;

这并不能从schedule中获得所有列,仅是一个显示其工作方式的示例。如果您需要各种查询(包括select *,尽管除了测试不是一个好习惯),您可以基于上述查询创建视图(包含计划中的所有列,但homeID和visitorID除外)被teams表中的子查询替换)。然后,您可以对该视图进行查询-它们将像原始表一样工作,在该表中直接具有团队名称。