有关超类型表的其他JOIN结果的JOIN表

时间:2016-03-17 12:57:21

标签: mysql sql

t1
-id (pk 1-to-1 references s.id)
-t2_id (fk)
-data

t2
-id (pk 1-to-1 references s.id)
-t3_id (fk)
-data

t3
-id (pk 1-to-1 references s.id)
-data

s
-id (pk)
-data

jt
-s_id (pk references s.id)
-ot_id (pk references ot.id)

ot
-id (pk)
-data

该应用确保t1t2t3的{​​{1}}值不相同。

我可以使用外键idt1轻松加入t2t3t2_id,从而产生一系列ID属于超类型表t3_id使用一对一的关系。

如何将联结表s加入上述结果,然后将其他表jt加入到该结果中?

我的最终结果是ot.data的集合ot

我正在考虑以下内容,但这看起来有点奇怪。

t1.id=123

或者可能是以下内容,或者是相关的查询?

SELECT ot.data
FROM t1
INNER JOIN t2 ON t2.id=t1.t2_id
INNER JOIN t3 ON t3.id=t2.t3_id
INNER JOIN jt ON jt.s_id=t1.id OR jt.s_id=t2.id OR jt.s_id=t3.id
INNER JOIN ot ON ot.id=jt.ot_id
WHERE t1.id=123;

或者也许?

SELECT ot.data
FROM ot
INNER JOIN jt ON jt.ot_id=ot.id
WHERE ot.id IN (
  SELECT COALESCE(s1.id,s2.id,s3.id)
  FROM t1
  INNER JOIN t2 ON t2.id=t1.t2_id
  INNER JOIN t3 ON t3.id=t2.t3_id
  LEFT OUTER JOIN s s1 ON s1.id=t1.id
  LEFT OUTER JOIN s s2 ON s2.id=t2.id
  LEFT OUTER JOIN s s3 ON s3.id=t3.id
  WHERE t1.id=123
);

1 个答案:

答案 0 :(得分:0)

好的,您有三组ID,并且您希望每个ID都有相应的数据。

在这里,我们列出了可以获得的数据:

SELECT
  s.id AS S_id, s.data AS S_data,
  ot.id AS OT_id, ot.data AS OT_DATA
FROM
  s
  INNER JOIN jt
    ON s.id = jt.s_id
  INNER JOIN ot
    ON jt.ot_id = ot.id

现在,如果我们不需要您拥有的三个表中的任何内容,则意味着,我们正在搜索上面查询结果中的所有记录,其中s.id包含在其中一个中表格。在语义上,这意味着3其中三个状态的条件,其中id包含在其中一个表中:

SELECT
  s.id AS S_id, s.data AS S_data,
  ot.id AS OT_id, ot.data AS OT_DATA
FROM
  s
  INNER JOIN jt
    ON s.id = jt.s_id
  INNER JOIN ot
    ON jt.ot_id = ot.id
WHERE
  EXISTS (SELECT * FROM t1 WHERE t1.id = s.id)
  OR EXISTS (SELECT * FROM t2 WHERE t2.id = s.id)
  OR EXISTS (SELECT * FROM t3 WHERE t3.id = s.id)

如果您需要来自t1..t3表的数据,只需将它们联合起来并将剩余部分加入到工会的结果中(正如sagi在他的回答中提到的那样)。

注意 测试以下解决方案是否更快。我不确定MySQL优化器是否可以在OR-ed谓词中找到快捷方式。

SELECT
  s.id AS S_id, s.data AS S_data,
  ot.id AS OT_id, ot.data AS OT_DATA
FROM
  s
  INNER JOIN jt
    ON s.id = jt.s_id
  INNER JOIN ot
    ON jt.ot_id = ot.id
WHERE
  EXISTS (
    SELECT 1 FROM t1 WHERE t1.id = s.id
    UNION ALL
    SELECT 1 FROM t2 WHERE t2.id = s.id
    UNION ALL
    SELECT 1 FROM t3 WHERE t3.id = s.id
  )

@TODO:对两个查询运行一个解释和一些测试,并使用看起来性能更好的那个。