SQL - 选择里面的联盟...在子句中

时间:2016-12-14 03:17:54

标签: mysql sql union mariadb

(第一次在这里发帖,希望发布不是一件傻事。如果你不想阅读文本,请阅读代码,因为这是一个简单的代码结构问题,我认为)

所以,今天我不得不做一个查询,让我知道哪些演员在同一个场景中扮演特定演员(在电影数据库的上下文中)。我认为表格细节不重要(但如果他们是我可以发布)。

在编写我的查询时,我意识到首先我必须执行两个查询结果的 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行选择Distinct sid,sordFrom MChar_ActPart MCAPInner join 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';

唯一不同的是括号。为什么一个工作而另一个不工作?

3 个答案:

答案 0 :(得分: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';

优化此版本的范围更广。

答案 1 :(得分:0)

您正在看到的错误与MariaDB上的错误有关((SELECT ...)UNION(SELECT ...))。

您可以在此链接上查看错误的状态:https://jira.mariadb.org/browse/MDEV-10028

注意:添加此作为答案,因为我认为是您面临的具体错误的正确答案。

答案 2 :(得分:0)

2 *哎哟。

WHERE (a,b) ...未得到很好的优化;避免它。

IN ( SELECT ... )现在经常得到很好的优化;避免它。

使用'派生子查询'将查询内部翻出来,从而避免使用这两种内容:

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
    ...