簡體   English   中英

加入涉及多個關聯的集成查詢

[英]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.idvideos.idaliases.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。 我認為重要的是視頻到別名的連接。

該評估是正確的。 僅在videosaliases之間需要連接,因為您可以通過performers_aliases加入users 保留它無害,除了如果出於某種原因必須重新分配別名,這意味着在多個相關表中更新performer_id 只是要記住一點-我懷疑您已經考慮過了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM