【问题标题】:SQL Joining Two or More from Table B with Common Data in Table ASQL将表B中的两个或多个与表A中的公共数据连接起来
【发布时间】:2010-04-01 06:06:49
【问题描述】:

注意:已编辑

实际情况是一系列活动,每个活动都有两个或多个参与者(例如运动队,尽管一个活动中可能有两个以上),其中只有一个是活动的主办方。每个唯一事件都有一个事件数据库表和一个具有唯一参与者的参与者数据库表。它们使用匹配表连接在一起。它们看起来像这样:

事件

事件 ID (PK)
(其他事件数据,如日期等)

参与者

参与者 ID (PK)
姓名

比赛

EventID(FK 到事件表)
参与者 ID(FK 到参与者)
主机(1 或 0,只有 1 个主机 = 每个 EventID 1 个)

如果我知道有两个参与者,我希望得到的结果是这样的:

EventID  PID-1(host)  Name-1 (host)  PID-2  Name-2
-------  -----------  -------------  -----  ------
    1         7       Lions            8    Tigers
    2        11       Dogs             9    Cats

同样,如果我知道有三个参与者,我该怎么做?

我怀疑答案相当简单,但出于某种原因,我并没有完全理解它。或者,这是非常困难的。 :)

如果这会影响可用的 SQL,我正在使用 MYSQL 5。

【问题讨论】:

  • 你不能真正构建一个返回可变数量列的查询......除非你知道任何给定事件的最大参与者数量......然后它'会是可行的(但一个非常非常糟糕的设计)。
  • 啊,嗯,好的,我会编辑的。如果我知道有 2 个或 3 个,会是什么样子?

标签: sql mysql


【解决方案1】:
CREATE TABLE event (
  pk int PRIMARY KEY
);

CREATE TABLE participant (
  pk int PRIMARY KEY,
  name varchar(255)
);

CREATE TABLE matchup (
  e int,
  p int,
  isHost bit,
  CONSTRAINT PK_matchup PRIMARY KEY (e,p)
);

-- Events with 2 particpants
INSERT INTO event (pk) VALUES (1);
INSERT INTO event (pk) VALUES (2);
INSERT INTO participant (pk, name) VALUES (7, 'Lions');
INSERT INTO participant (pk, name) VALUES (8, 'Tigers');
INSERT INTO participant (pk, name) VALUES (11, 'Dogs');
INSERT INTO participant (pk, name) VALUES (9, 'Cats');
INSERT INTO matchup (e, p, isHost) VALUES (1, 7, 1);
INSERT INTO matchup (e, p, isHost) VALUES (1, 8, 0);
INSERT INTO matchup (e, p, isHost) VALUES (2, 11, 1);
INSERT INTO matchup (e, p, isHost) VALUES (2, 9, 0);

-- Events with 3 particpants
INSERT INTO event (pk) VALUES (3);
INSERT INTO participant (pk, name) VALUES (1, 'One');
INSERT INTO participant (pk, name) VALUES (2, 'Two');
INSERT INTO participant (pk, name) VALUES (3, 'Three');
INSERT INTO matchup (e, p, isHost) VALUES (3, 1, 0);
INSERT INTO matchup (e, p, isHost) VALUES (3, 2, 1);
INSERT INTO matchup (e, p, isHost) VALUES (3, 3, 0);

-- SELECT the events with 2 participants
SELECT
  event.pk AS EventID,
  p1.pk    AS Pid1_Host,
  p1.name  AS Name1_Host,
  p2.pk    AS Pid2,
  p2.name  AS Name2
FROM
             event
  INNER JOIN matchup m1 ON (event.pk = m1.e)
  INNER JOIN matchup m2 ON (event.pk = m2.e)
  INNER JOIN participant p1 ON (m1.isHost = 1 AND m1.p = p1.pk)
  INNER JOIN participant p2 ON (m2.isHost != 1 AND m2.p = p2.pk)
WHERE
  event.pk IN (SELECT e FROM matchup GROUP BY e HAVING COUNT(*) = 2)

+---------+-----------+------------+------+--------+
| EventID | Pid1_Host | Name1_Host | Pid2 | Name2  |
+---------+-----------+------------+------+--------+
|       1 |         7 | Lions      |    8 | Tigers |
|       2 |        11 | Dogs       |    9 | Cats   |
+---------+-----------+------------+------+--------+
2 rows in set (0.00 sec)


-- SELECT the events with 3 participants
SELECT
  event.pk AS EventID,
  p1.pk    AS Pid1_Host,
  p1.name  AS Name1_Host,
  p2.pk    AS Pid2,
  p2.name  AS Name2,
  p3.pk    AS Pid3,
  p3.name  AS Name3
FROM
             event
  INNER JOIN matchup m1 ON (event.pk = m1.e)
  INNER JOIN matchup m2 ON (event.pk = m2.e)
  INNER JOIN matchup m3 ON (event.pk = m3.e)
  INNER JOIN participant p1 ON (m1.isHost = 1 AND m1.p = p1.pk)
  INNER JOIN participant p2 ON (m2.isHost != 1 AND m2.p = p2.pk)
  INNER JOIN participant p3 ON (m3.isHost != 1 AND m3.p = p3.pk AND p3.pk != p2.pk)
WHERE
      p2.pk < p3.pk -- to remove spurious rearrangements of Name2 and Name3
  AND event.pk IN (SELECT e FROM matchup GROUP BY e HAVING COUNT(*) = 3)


+---------+-----------+------------+------+-------+------+-------+
| EventID | Pid1_Host | Name1_Host | Pid2 | Name2 | Pid3 | Name3 |
+---------+-----------+------------+------+-------+------+-------+
|       3 |         2 | Two        |    1 | One   |    3 | Three |
+---------+-----------+------------+------+-------+------+-------+
1 row in set (0.00 sec)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 2020-10-09
    • 2018-12-14
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    相关资源
    最近更新 更多