如何修复mysql

时间:2016-09-07 07:50:17

标签: mysql sql

我试图创建一个相关的子查询,但我无法弄清楚我做错了什么。每当我尝试运行它时,我都会在条款'中获得Unknow colunm:

所以给出了这个架构

create table promotion(PK int, name varchar(255));
create table uiExperienceLevel(PK int, code varchar(255));
create table xp2promo(SourcePk int, TargetPk int);

insert into promotion values(1,'Desktop promotion');
insert into promotion values(2,'Ipad promotion');

insert into uiExperienceLevel values(1,'Desktop');
insert into uiExperienceLevel values(2,'Iphone');
insert into uiExperienceLevel values(3,'Ipad');

insert into xp2Promo values(1,1);
insert into xp2Promo values(2,2);

为什么此查询不起作用?

SELECT  promo.PK  FROM promotion as promo 
    WHERE ('Desktop' in 
            (SELECT  uiXpLevel.Code  FROM xp2promo xp2promo 
                                     JOIN uiExperienceLevel uiXpLevel 
                                        ON  uiXpLevel.PK  =  xp2promo.TargetPK  
                                          AND  xp2promo.SourcePK  =  promo.PK )
          )

每次运行此操作时都会出现以下错误。

Error Code: 1054. Unknown column 'promo.PK' in 'on clause'
PS:我知道我可以使用内连接做同样的事情,不仅可以工作,而且还有更好的性能

SELECT promo.Pk FROM Promotion as Promo
                JOIN xp2promo xp2promo ON  xp2promo.SourcePK  =  promo.PK
                JOIN uiExperienceLevel uiXpLevel ON  uiXpLevel.PK  =  xp2promo.TargetPK 
       WHERE uiXpLevel.Code ='Desktop'

但是出于学术目的,我想知道如何修复子查询

编辑:好的,我弄明白了为什么,

根据mysql官方文档https://dev.mysql.com/doc/refman/5.5/en/correlated-subqueries.html

enter image description here

所以我只需要反转逻辑,从内部查询中给出桌面促销的ID,并比较外面的pks,就像这样

SELECT  promo.PK  FROM promotion as promo 
    WHERE (promo.PK  in 
            (SELECT  xp2promo.SourcePk  FROM xp2promo xp2promo 
                                     JOIN uiExperienceLevel uiXpLevel 
                                        ON  uiXpLevel.PK  =  xp2promo.TargetPK  
                                          WHERE uiXpLevel.Code = 'Desktop' )
          )

无论如何,我会将问题作为对任何面临同样问题的人的参考

2 个答案:

答案 0 :(得分:1)

您无法从子查询中访问表。在子查询中再次定义表格。喜欢这个

SELECT  promo.PK  
FROM promotion as promo 
    WHERE ('Desktop' in 
            (SELECT  uiXpLevel.Code  FROM promotion as promoInner
                                     JOIN xp2promo xp2promo 
                                        ON xp2promo.SourcePK  =  promoInner.PK
                                     JOIN uiExperienceLevel uiXpLevel 
                                        ON  uiXpLevel.PK  =  xp2promo.TargetPK )
          )

答案 1 :(得分:0)

来自WHERE的引用工作正常,v5.6并且它必须根据文档工作。

SELECT promo.PK  
FROM promotion as promo 
WHERE 'Desktop' in 
            (SELECT  uiXpLevel.Code  
             FROM xp2promo xp2promo 
             JOIN uiExperienceLevel uiXpLevel 
                    ON  uiXpLevel.PK  =  xp2promo.TargetPK  
             WHERE xp2promo.SourcePK  =  promo.PK )

真正的原因是加入MySQL 5.0.12中的处理更改 https://dev.mysql.com/doc/refman/5.5/en/join.html

  

以前,ON子句可以引用名为to的表中的列   这是正确的。现在一个ON子句只能引用它的操作数。

     

示例:

CREATE TABLE t1 (i1 INT);
CREATE TABLE t2 (i2 INT); 
CREATE TABLE t3 (i3 INT);
SELECT * FROM t1 JOIN t2 ON (i1 = i3) JOIN t3; 
     

以前,SELECT语句是合法的。现在声明失败了   'on clause'中的未知列'i3'错误,因为i3是t3中的列,   这不是ON子句的操作数。