我在dba上发布了这个,但我没有得到任何回复所以我在这里添加了它。
这是我的SQLFiddle
我在修复此查询时需要一些帮助。这个问题很简单,但我还是无法解决。让我解释它目前的工作背景,然后解释我需要整合的内容。
首先,这是我目前的表格。
用户(表演者)表
users表列出了所有用户。我们将假设此查询所有选定的用户都是类型执行者。
users
-----------
id
hash
first_name
last_name
这是users表的转储:
id hash first_name last_name
1 092ee63c6698851ba72183388bff1b3b Jonathan Kushner
2 2d234affe1d08c3394cd499f297d7380 Dustin Kushner
别名表
别名表列出了所有别名。我们将此表连接到另一个表中的表演者。
aliases
----------
id
hash
title
这是别名表的转储:
id hash title
1 436etgfgdggdd Greatness
2 54645655gggdgdg Mr.Darkness
3 ffsafsdsfdfdssf Mr.Shadow
performers_aliases表
performers_aliases表将类型执行者的用户连接到别名表中的别名。
performers_aliases
----------
id
hash
performer_id (connects to the users.id column)
alias_id
这里是performers_aliases表的转储:
id hash performer_id alias_id
1 dsaadsasdadsads 1 1
2 d4544534553 2 2
3 adfasdadsadsa 2 3
视频表
视频表列出了所有视频。
videos
----------
id
hash
title
这是视频表的转储:
id hash title
1 89efaed413163be4557133266ce295b4 crazy sports blooper
videos_performers
视频表演者表将视频连接到表演者类型的用户。
videos_performers
----------
id
hash
video_id
performer_id (connects to the users.id column)
继承了视频表演者的表:
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
Dustin Kushner Mr.Shadow crazy sports blooper
正如您所看到的,此视频包含2位表演者--Jonathan Kushner和Dustin Kushner。但是,Dustin有2个别名,所以它有2个记录
我想做的是将视频表演者通过别名连接到视频,因此他没有为Dustin创建2条记录,因为他有2个别名,它只会连接到用于的别名该特定视频。
例如,此视频的输出为:
first_name last_name alias video
Jonathan Kushner Greatness crazy sports blooper
Dustin Kushner Mr.Darkness crazy sports blooper
此结果集现在只显示2个记录,一个用于Dustin作为Mr.Darkness,一个用于Jonathan作为Greatness。你会注意到,由于Mr.Shadow没有被用作该视频的别名,因此不再存在Dustin作为Mr.Shadow的记录。
这是我目前关于如何解决这个问题的工作。我创建了一个videos_performers_aliases
表,用于将视频与表演者连接到别名。
我不认为我需要performer_id列,但无论如何都喜欢它。我认为重要的是视频别名连接。
videos_performers_aliases
--------------------
id
hash
video_id
performer_id
alias_id
以下是videos_performers_aliases表的转储:
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
这暗示我们有一位表演者是达斯特先生,一位表演者是伟大的。如您所见,Mr.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
就我而言,这是最重要的。
任何帮助都将不胜感激。
答案 0 :(得分:1)
您表达查询的方式中缺少的部分是videos_perfomers_aliases
联接中的另一个条件,即将其加入videos.id
和aliases.id
表。
LEFT JOIN `videos_performers_aliases`
ON `videos_performers_aliases`.`video_id` = `videos`.`id`
AND `videos_performers_aliases`.`alias_id` = `aliases`.id`
但是,使用LEFT JOIN
实际上会导致返回两个别名。而使用INNER JOIN
将仅返回连接的别名。
INNER JOIN `videos_performers_aliases`
ON `videos_performers_aliases`.`video_id` = `videos`.`id`
AND `videos_performers_aliases`.`alias_id` = `aliases`.id`
以下是修改后的版本以生成预期结果:http://sqlfiddle.com/#!9/ec26c/21
但整个查询可以简化。由于videos_performers_aliases
已包含视频和别名信息,因此它会为此查询(以及其他人)呈现videos_performers
表格。您可以使用此链执行整个查询:
users(id) --> (performer_id)performers_aliases(alias_id) --> (id)aliases(id) --> (alias_id)videos_performers_aliases(video_id) --> (id)videos
因此可以消除其中一个连接,并使用videos_performers_aliases
简化连接条件,只需要一个部分。
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
此处正在运行,产生您的预期结果:http://sqlfiddle.com/#!9/ec26c/19
关于videos_performers_aliases
,你说:
我认为我不需要
performer_id
列,但无论如何都喜欢它。我认为重要的是视频别名连接。
评估是正确的。只有videos
和aliases
之间才需要建立连接,因为您可以通过users
加入performers_aliases
。保留它是没有害处的,除非由于某种原因你必须重新分配别名,这意味着更新多个相关表中的performer_id
。请记住一些事情 - 我怀疑你已经考虑过了。