2016-12-14 50 views
1

(這裏第一次發佈,希望它不是一個愚蠢的事情發佈。只是閱讀代碼,如果你不想閱讀文本,因爲它是一個簡單的代碼結構問題,我認爲)SQL - 選擇內部的聯盟Where ...條款

所以,今天我不得不作出一個查詢,讓我知道哪些演員在同一個場景中出演特定演員(在電影數據庫的上下文中)。我不認爲表格的細節很重要(但如果他們是我可以發佈)。

在寫我的查詢時,我意識到首先我必須執行兩個查詢結果的Union(這給了我場景所屬的腳本的id,以及該場景內部的順序腳本),然後從這些場景中選擇所有演員。場景分爲動作部分和言語線,演員只與這些部分相連,而不是直接與場景相連。

我已經有一個可行的答案(我仍然需要做另一個工會,但這很簡單),但我想了解爲什麼它會工作,爲什麼我的第一個答案沒有工作。我做的唯一的事情就是刪除括號。

所以這個答案不工作

Select Distinct name 
From Staff S 
Inner join MChar_ActPart MCAP on S.stid=MCAP.aid 
Where (sid, sord) in ((Select Distinct sid, sord 
         From MChar_SpLine MCSL 
         Inner join Staff S on MCSL.aid = S.stid 
         Where name = 'John Idle')      
         Union 
         (Select Distinct sid, sord 
         From MChar_ActPart MCAP 
         Inner join Staff S on MCAP.aid = S.stid 
         Where name = 'John Idle')) 
And name != 'John Idle'; 

我得到這個錯誤。 「SQL錯誤(1064):您的SQL語法錯誤;檢查與您的MariaDB服務器版本相對應的手冊,以找到正確的語法以在'Union(在第9行選擇不同的sid,sordFrom MChar_ActPart MCAPInner加入Staff S)

但是這一次確實工作:?

Select Distinct name 
From Staff S 
Inner join MChar_ActPart MCAP on S.stid=MCAP.aid 
Where (sid, sord) in (Select Distinct sid, sord 
         From MChar_SpLine MCSL 
         Inner join Staff S on MCSL.aid = S.stid 
         Where name = 'John Idle' 
         Union 
         Select Distinct sid, sord 
         From MChar_ActPart MCAP 
         Inner join Staff S on MCAP.aid = S.stid 
         Where name = 'John Idle') 
And name != 'John Idle'; 

是唯一不同的是括號爲什麼一個工作和其他不工作

回答

0

您正在看到的錯誤與MariaDB上的錯誤有關(當您正在執行操作時((SELECT ...)UNION(SELECT ...))。

您可以檢查錯誤的狀態此鏈接:https://jira.mariadb.org/browse/MDEV-10028

注:添加此作爲一個答案,因爲我認爲是正確的答案,你所面對的特定錯誤。

1

unionselect distinct是多餘的我會的。強烈建議您將查詢寫爲:

Select Distinct name 
From Staff S Inner join 
    MChar_ActPart MCAP 
    on S.stid = MCAP.aid 
Where ((sid, sord) in (Select sid, sord 
         From MChar_SpLine MCSL Inner Join 
          Staff S 
          on MCSL.aid = S.stid 
         Where name = 'John Idle' 
        ) or 
     (sid, sord) in (Select sid, sord 
         From MChar_ActPart MCAP Inner Join 
          Staff S 
          on MCAP.aid = S.stid 
         Where name = 'John Idle' 
        ) 
    ) and 
     name <> 'John Idle'; 

優化此版本的範圍還有很多。

+0

首先,感謝您的回答!那麼,通常使用「或」比執行兩個「子結果」的「聯盟」更好? 哦,我仍然很好奇爲什麼第一個選項導致錯誤。你能幫我解決嗎? – Slna

+1

似乎與一個錯誤有關,請點擊這裏查看:https://jira.mariadb.org/browse/MDEV-10028 –

+0

@Sina。 。 。我不確定爲什麼第一個版本會返回錯誤,但是您似乎理解了語法差異。除了「查詢解析器看起來如何工作」之外,沒有太多可說的。你的查詢的性能問題是'union'或'select distinct'需要做額外的工作才能刪除重複項。 –

0

2 * Ouch。

WHERE (a,b) ...沒有很好的優化;躲開它。

IN (SELECT ...)現在經常被優化;躲開它。

使用「派生子查詢」轉內而外的查詢,從而避免雙方ouchies:

SELECT ... 
    FROM ((SELECT sid, sord FROM ...) 
      UNION ALL -- or DISTICT 
      (SELECT sid, sord FROM ...) 
     ) AS u 
    JOIN ... AS x 
     ON x.sid = u.sid 
     AND x.sord = u.sord 
    ...