我是否错误地进行嵌套连接?

时间:2017-06-29 16:56:45

标签: mysql sql join

民间!我在这个问题上摸不着头脑。当我在最后一次加入中添加UserRole部分时,我开始看到此错误。我究竟做错了什么? MySQL中的嵌套连接数是否有限制?

错误:

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ON Opportunity.AccountId = AccountD.Id' at line 31

表结构

Opportunity
-----------
Id, Name, AccountId, OwnerId

Account
-------
Id,Name,OwnerId

User
----
Id,Name,UserRoleId

UserRole
--------
Id,Name

RecordType
----------
Id,Name

SQL

SELECT 
Opportunity.Id AS 'Opportunity_ID',
Opportunity.Opportunity_Number__c AS 'Opportunity_Number__c',
UserA.Name AS 'Opportunity_Owner',
Opportunity.Name AS 'Opportunity_Name',
Opportunity.Probability AS 'Opportunity_Probability',
Opportunity.StageName AS 'Opportunity_Stage',
Opportunity.Amount AS 'Opportunity_Amount',
Opportunity.CloseDate AS 'Opportunity_CloseDate',
Opportunity.Roll_Out_End_Formula__c AS 'Opportunity_Rollout_End_Date',
RecordTypeA.Name AS 'Record_Type',
Opportunity.Division__c AS 'Division',
Pricebook2.Name AS 'Price_Book',
Opportunity.Won_Date__c AS 'Opportunity_Won_Date',
Opportunity.CreatedDate AS 'Opportunity_Created_Date',
AccountA.Id AS 'Account_ID',
AccountA.Name AS 'Account_Name',
AccountA.Type AS 'Account_Type',
RecordTypeB.Name AS 'Account_Record_Type',
AccountA.Key_Account__c AS 'Key_Account',
UserB.Name AS 'Account_Owner',
UserB.Sales_Team__c AS 'Account_Owner_Sales_Team',
UserRoleA.Name AS 'Account_Owner_User_Role'
FROM Opportunity
LEFT JOIN User UserA ON Opportunity.OwnerId = UserA.Id
LEFT JOIN RecordType RecordTypeA ON Opportunity.RecordTypeId = RecordTypeA.Id
LEFT JOIN Pricebook2 ON Opportunity.Pricebook2Id = Pricebook2.Id
LEFT JOIN Account AccountA ON Opportunity.AccountId = AccountA.Id
LEFT JOIN Account AccountB JOIN RecordType RecordTypeB ON AccountB.RecordTypeId = RecordTypeB.Id ON Opportunity.AccountId = AccountB.Id
LEFT JOIN Account AccountC JOIN User UserB ON AccountC.OwnerId = UserB.Id ON Opportunity.AccountId = AccountC.Id
LEFT JOIN Account AccountD JOIN User UserC JOIN UserRole UserRoleA ON UserC.UserRoleId = UserRoleA.Id ON AccountD.OwnerId = UserC.Id ON Opportunity.AccountId = AccountD.Id
LIMIT 5\G

3 个答案:

答案 0 :(得分:3)

如果您想对您的"帐户"执行嵌套连接实例,你必须使用括号。

{{1}}

编辑:我修复了最后一行(带有AccountD的那一行)。

答案 1 :(得分:0)

这看起来就像使用查询设计器时自动生成的那种代码(实际上往往是一个死的赠品)

说它确实有效,但它很难阅读。

用以下内容替换你的from子句,看看你是否还有问题......

FROM 
    Opportunity
    LEFT JOIN User UserA 
        ON Opportunity.OwnerId = UserA.Id
    LEFT JOIN RecordType RecordTypeA 
        ON Opportunity.RecordTypeId = RecordTypeA.Id
    LEFT JOIN Pricebook2 
        ON Opportunity.Pricebook2Id = Pricebook2.Id
    LEFT JOIN Account AccountA 
        ON Opportunity.AccountId = AccountA.Id  
    JOIN RecordType RecordTypeB 
        ON AccountB.RecordTypeId = RecordTypeB.Id 
    LEFT JOIN Account AccountB 
        ON Opportunity.AccountId = AccountB.Id  
    JOIN User UserB 
        ON AccountC.OwnerId = UserB.Id 
    LEFT JOIN Account AccountC 
        ON Opportunity.AccountId = AccountC.Id  
    LEFT JOIN Account AccountD 
        ON Opportunity.AccountId = AccountD.Id
    JOIN User UserC 
        ON AccountD.OwnerId = UserC.Id 
    JOIN UserRole UserRoleA 
        ON UserC.UserRoleId = UserRoleA.Id 

答案 2 :(得分:0)

嵌套连接不是您在查询中编写的,而是DBMS用于执行连接的技术。

当你加入两个表,比如from a join b on a.aa = b.bb时,DBMS有几种方法可以将它付诸实践。例如,它可以阅读a并按aa对其进行排序。然后它会显示b并按bb对其进行排序。然后它将按顺序读取两个结果列表,并将所有匹配写入最终结果列表。

另一种方法是从a读取一条记录,然后阅读b以查找aa = bb上的所有匹配项。然后,它将从a读取下一条记录并再次读取b以查找第二条记录的匹配项,依此类推。此方法称为嵌套连接。

但是,您只需告诉DBMS要加入的内容以及要加入的条件,而不是使用哪种方法。 DBMS将(希望)为每次加入找到最佳方法。

关于您的查询:您从Opportunity中选择所有记录。然后你加入表User。因此,出于某种原因,您希望有一些机会不拥有所有者,但仍希望获得机会的结果行。 RecordTypePricebook2Account相同;你希望这些表中有一些机会不匹配,但希望机会仍在结果中。从名称我们可以收集到列上有外键,例如RecordTypeId = 'X''X'中不存在RecordType时,您无法存储Account的商机。所以你显然是外连接,因为这些列是可选的(可为空)。

然后它变得很奇怪。您尝试再次加入CROSS JOIN。但是这次你没有指定一个ON子句。这是无效的SQL,但MySQL让它滑倒。联接在内部变为Opportunity,即您加入到目前为止每个帐户的每一行。假设您在Account中有1000条记录,在RecordType中有500条记录,这会产生500,000行。然后你突然再次加入AccountB.RecordTypeId = RecordTypeB.Id。但这次你想要帐户的记录类型,而不是机会。您加入RecordTypeId因此,每个拥有ON null帐户的行都会被解散,其他行会被保留。然后你有另一个错位的WHERE子句。我不知道MySQL如何解释这一点。这可能导致语法错误或将其视为ON子句,或将其视为前ON子句的一部分。这是无效的并且应该引发错误,但是之前缺少的'lalala' -- this is a string conform with the SQL standard lalala -- this is a name conform with the SQL standard "lalala" -- this is a name conform with the SQL standard -- it could also be a string in MySQL violating the SQL standard `lalala` -- this is a name in MySQL violating the SQL standard 子句也是如此。

长话短说:你在这里做错了。我们必须知道预期的结果才能做到这一点。

除此之外:单引号用于字符串文字:

FROM opprtunity o
JOIN User u ON u.Id = o.OwnerId

使用短别名更容易阅读包含许多表的查询

<input type="text" ng-model="newTesting">


 data: {newName: $scope.newName, newPhone: $scope.newPhone, newTest: $scope.newTest }