2016-12-14 70 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 
    ...