Mysql 涉及多个关联的联接集成查询
我在dba上发布了这篇文章,但没有收到任何回复,所以我把它添加到了这里 这是我的 我需要一些帮助来解决这个问题。这个问题相当简单,但我就是解决不了。让我解释一下它目前的工作背景,以及我需要集成的内容 首先,这是我目前的表格 用户(表演者)表 用户表列出了所有用户。对于这个查询,我们将假设所有选择的用户都是类型执行者Mysql 涉及多个关联的联接集成查询,mysql,join,left-join,Mysql,Join,Left Join,我在dba上发布了这篇文章,但没有收到任何回复,所以我把它添加到了这里 这是我的 我需要一些帮助来解决这个问题。这个问题相当简单,但我就是解决不了。让我解释一下它目前的工作背景,以及我需要集成的内容 首先,这是我目前的表格 用户(表演者)表 用户表列出了所有用户。对于这个查询,我们将假设所有选择的用户都是类型执行者 users ----------- id hash first_name last_name 以下是用户表的转储: id hash
users
-----------
id
hash
first_name
last_name
以下是用户表的转储:
id hash first_name last_name
1 092ee63c6698851ba72183388bff1b3b Jonathan Kushner
2 2d234affe1d08c3394cd499f297d7380 Dustin Kushner
id hash video_id performer_id
1 3a7e0f543af5152c623ad8156079bb73 1 1
2 c0abf5f50f6382c744a9359d7dbc4c8c 1 2
别名表
“别名”表列出了所有别名。我们将此表连接到另一个表中的表演者
aliases
----------
id
hash
title
以下是别名表的转储:
id hash title
1 436etgfgdggdd Greatness
2 54645655gggdgdg Mr.Darkness
3 ffsafsdsfdfdssf Mr.Shadow
id hash performer_id alias_id
1 dsaadsasdadsads 1 1
2 d4544534553 2 2
3 adfasdadsadsa 2 3
id hash video_id performer_id alias_id
1 fdsa97asd987das7das97 1 1 1
2 dfdfsdfsfdsdfsdfsfd 1 2 2
表演者\u别名表
执行者别名表将类型执行者的用户连接到别名表中的别名
performers_aliases
----------
id
hash
performer_id (connects to the users.id column)
alias_id
下面是performers\u Alias表的转储:
id hash title
1 436etgfgdggdd Greatness
2 54645655gggdgdg Mr.Darkness
3 ffsafsdsfdfdssf Mr.Shadow
id hash performer_id alias_id
1 dsaadsasdadsads 1 1
2 d4544534553 2 2
3 adfasdadsadsa 2 3
id hash video_id performer_id alias_id
1 fdsa97asd987das7das97 1 1 1
2 dfdfsdfsfdsdfsdfsfd 1 2 2
视频表
视频表列出了所有视频
videos
----------
id
hash
title
下面是视频表的转储:
id hash title
1 89efaed413163be4557133266ce295b4 crazy sports blooper
视频\u表演者
“视频表演者”表将视频连接到类型为“表演者”的用户
videos_performers
----------
id
hash
video_id
performer_id (connects to the users.id column)
下面是视频表演者表的转储:
id hash first_name last_name
1 092ee63c6698851ba72183388bff1b3b Jonathan Kushner
2 2d234affe1d08c3394cd499f297d7380 Dustin Kushner
id hash video_id performer_id
1 3a7e0f543af5152c623ad8156079bb73 1 1
2 c0abf5f50f6382c744a9359d7dbc4c8c 1 2
嗯。现在让我向您展示我当前的查询:
SELECT
`users`.`first_name`,
`users`.`last_name`,
`aliases`.`title` AS `alias`,
`videos`.`title` AS `video`
FROM
`users`
LEFT JOIN `performers_aliases`
ON `performers_aliases`.`performer_id` = `users`.`id`
LEFT JOIN `aliases`
ON `aliases`.`id` = `performers_aliases`.`alias_id`
LEFT JOIN `videos_performers`
ON `videos_performers`.`performer_id` = `users`.`id`
LEFT JOIN `videos`
ON `videos`.`id` = `videos_performers`.`video_id`
WHERE (
`videos`.`hash` = '89efaed413163be4557133266ce295b4'
)
ORDER BY `users`.`last_name` ASC
此查询执行以下操作:
first_name last_name alias video
Jonathan Kushner Greatness crazy sports blooper
Dustin Kushner Mr.Darkness crazy sports blooper
- 选择作为视频执行者的用户。我们需要包括别名表来获取执行者的别名。(注意:执行者可以有多个别名)
first_name last_name alias video
Jonathan Kushner Greatness crazy sports blooper
Dustin Kushner Mr.Darkness crazy sports blooper
Dustin Kushner Mr.Shadow crazy sports blooper
如您所见,此视频包含两名表演者-乔纳森·库什纳和达斯汀·库什纳。但是,Dustin有两个别名,因此它有两张他的记录
我想做的是将视频表演者通过别名连接到视频中,这样Dustin就不会有两张记录,因为他有两个别名,它只会连接到用于该特定视频的别名。
例如,此视频的输出为:
first_name last_name alias video
Jonathan Kushner Greatness crazy sports blooper
Dustin Kushner Mr.Darkness crazy sports blooper
这个结果集现在只显示了两项记录,一项是达斯汀扮演的黑暗先生,另一项是乔纳森扮演的伟大人物。你会注意到Dustin不再有作为Shadow先生的记录,因为Shadow先生没有被用作该视频的别名
这是我目前的工作,关于如何解决这个问题。我创建了一个videos\u performers\u alias
表,将视频与表演者连接到别名。
我想我不需要performer_id列,但我还是喜欢它。我认为重要的是视频到别名的连接
videos_performers_aliases
--------------------
id
hash
video_id
performer_id
alias_id
以下是视频\u表演者\u别名表的转储:
id hash title
1 436etgfgdggdd Greatness
2 54645655gggdgdg Mr.Darkness
3 ffsafsdsfdfdssf Mr.Shadow
id hash performer_id alias_id
1 dsaadsasdadsads 1 1
2 d4544534553 2 2
3 adfasdadsadsa 2 3
id hash video_id performer_id alias_id
1 fdsa97asd987das7das97 1 1 1
2 dfdfsdfsfdsdfsdfsfd 1 2 2
然后我将修改上面的查询,如下所示:
SELECT
`users`.`first_name`,
`users`.`last_name`,
`aliases`.`title` AS `alias`,
`videos`.`title` AS `video`
FROM
`users`
LEFT JOIN `performers_aliases`
ON `performers_aliases`.`performer_id` = `users`.`id`
LEFT JOIN `aliases`
ON `aliases`.`id` = `performers_aliases`.`alias_id`
LEFT JOIN `videos_performers`
ON `videos_performers`.`performer_id` = `users`.`id`
LEFT JOIN `videos`
ON `videos`.`id` = `videos_performers`.`video_id`
LEFT JOIN `videos_performers_aliases`
ON `videos_performers_aliases`.`video_id` = `videos`.`id`
WHERE (
`videos`.`hash` = '89efaed413163be4557133266ce295b4'
)
ORDER BY `users`.`last_name` ASC
如您所见,我在查询中添加了以下内容:
LEFT JOIN `videos_performers_aliases`
ON `videos_performers_aliases`.`video_id` = `videos`.`id`
我希望我的输出如下:
first_name last_name alias video
Jonathan Kushner Greatness crazy sports blooper
Dustin Kushner Mr.Darkness crazy sports blooper
这暗示着我们有一个表演者是黑暗先生,一个表演者是伟大的。如您所见,Shadow先生不在结果集中
不幸的是,这里的结果集仍然是:
first_name last_name alias video
Jonathan Kushner Greatness crazy sports blooper
Dustin Kushner Mr.Darkness crazy sports blooper
Dustin Kushner Mr.Shadow crazy sports blooper
这是我能做到的
任何帮助都将不胜感激。您表达查询的方式中缺少的部分是
videos\u performers\u alias
join中的另一个条件,即将其连接到videos.id
和alias.id
表
LEFT JOIN `videos_performers_aliases`
ON `videos_performers_aliases`.`video_id` = `videos`.`id`
AND `videos_performers_aliases`.`alias_id` = `aliases`.id`
但是,使用左连接实际上会导致返回两个别名。相反,使用内部联接将只返回连接的别名
INNER JOIN `videos_performers_aliases`
ON `videos_performers_aliases`.`video_id` = `videos`.`id`
AND `videos_performers_aliases`.`alias_id` = `aliases`.id`
以下是为产生预期结果而修改的版本:
更好的方法是使用较少的联接:
但整个查询可以简化。由于videos\u performers\u别名
已包含视频和别名信息,因此它会使videos\u performers
表不需要此查询(可能还有其他查询)。您可以使用此链执行整个查询:
users(id) --> (performer_id)performers_aliases(alias_id) --> (id)aliases(id) --> (alias_id)videos_performers_aliases(video_id) --> (id)videos
因此,可以消除其中一个连接,并使用videos\u performers\u别名简化连接条件,从而只需要一个部分
SELECT
`users`.`first_name`,
`users`.`last_name`,
`aliases`.`title` AS alias,
`videos`.`title` AS video
FROM
`users`
LEFT JOIN `performers_aliases`
ON `performers_aliases`.`performer_id` = `users`.`id`
LEFT JOIN `aliases`
ON `aliases`.`id` = `performers_aliases`.`alias_id`
LEFT JOIN `videos_performers_aliases`
ON videos_performers_aliases.alias_id = aliases.id
LEFT JOIN `videos`
ON `videos`.id = videos_performers_aliases.video_id
WHERE (
`videos`.`hash` = '89efaed413163be4557133266ce295b4'
)
ORDER BY `users`.`last_name` ASC
在这里,它正在发挥作用,产生您的预期结果:
关于视频\u表演者\u别名
,您说:
我想我不需要performer\u id
列,但我还是喜欢它。我认为重要的是视频到别名的连接
videos_performers_aliases
--------------------
id
hash
video_id
performer_id
alias_id
这一评估是正确的。只有视频
和别名
之间才需要连接,因为您可以通过执行者\别名
加入用户
。保留它并不有害,除非出于某种原因必须重新分配别名,这意味着更新多个相关表中的performer\u id
。需要记住的是,我想你已经考虑过了。视频、表演者、别名表的当前内容是什么?请将它们添加到,然后在上面编辑以包含此链接。对其他访问此网站的人来说,提炼出你上面的长篇大论将非常有帮助。@MichaelBerkowski完成了。你有几个左连接,这实际上是你问题的一部分。如果视频89EFAED413163BE455713266CE295B4
没有关联的执行者,您想为名字、姓氏、别名返回空值,还是不想返回行?@MichaelBerkowski如果没有关联的执行者,我不想返回任何行。我不明白为什么我的任何左连接都是不必要的,它们都是连接到查询的部分。明白了。“我想我已经找到了正确的解决方案。”杰库什纳,我很高兴。祝你好运