![](/img/trans.png)
[英]Need help with an SQL query involving multiple tables - Join not an option
[英]Join integration query involving multiple associations
我在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。 但是,達斯汀有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的Darkness先生,另一個是Jonathan的Greatness。 您會注意到,由於沒有將Shadow用作該視頻的別名,因此不再有Dustin作為Shadow的記錄。
這是我目前關於如何解決此問題的工作。 我已經創建了一個videos_performers_aliases
表,該表將視頻和表演者連接到別名。 我不認為我需要performer_id列,但是無論如何我都喜歡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
這暗示着我們有一位表演者為Darkness先生,另一位表演者為Greatness。 如您所見,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_perfomers_aliases
另一個條件,該videos_perfomers_aliases
將其同時videos.id
到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
簡化聯接條件, 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
列,但是無論如何我都喜歡id。 我認為重要的是視頻到別名的連接。
該評估是正確的。 僅在videos
和aliases
之間需要連接,因為您可以通過performers_aliases
加入users
。 保留它無害,除了如果出於某種原因必須重新分配別名,這意味着在多個相關表中更新performer_id
。 只是要記住一點-我懷疑您已經考慮過了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.