【问题标题】:Use a field in where clause without select it在 where 子句中使用字段而不选择它
【发布时间】:2019-08-28 16:04:43
【问题描述】:

我试图在 where 子句中使用字段而不选择它

类似于 SELECT field 1 FROM table WHERE field2 = 'foo'

$where= $onlyissuing ? " WHERE ISSUE = 1" : "";
$sql="
SELECT c.*
     , d.Name_fr as DEVISE 
  FROM 
     ( SELECT a.Currency_ISO3 as value
            , a.Rank as ISSUE
            , b.Name_fr as PAYS 
         FROM countries_currencies a
            , countrylist b
        where a.Country_ISO3 = b.Country_ISO3
     ) c
     , currencylist d 
 where c.value = d.Currency_ISO3
 ";
$sql='
SELECT e.*
     , CONCAT(e.value, " - ", e.PAYS, " - ", e.DEVISE ) AS label 
  FROM ('.$sql.')e
  ';
 $sql = $sql.$where;

因此它可以工作,但如果我不选择 a.Rank 作为问题,我会收到错误 致命错误:未捕获的 PDOException:SQLSTATE [42S22]:找不到列:1054 'where 子句'中的未知列 'ISSUE'

感谢 cmets,工作解决方案:

$sql='SELECT a.Currency_ISO3 as value, b.Name_fr as PAYS, c.Name_fr as DEVISE, CONCAT(a.Currency_ISO3, " - ", b.Name_fr, " - ", c.Name_fr ) AS label FROM countries_currencies a INNER JOIN countrylist b on a.Country_ISO3=b.Country_ISO3 INNER JOIN currencylist c on a.Currency_ISO3=c.Currency_ISO3 WHERE a.Rank=1';

【问题讨论】:

  • (1) 使用标准的显式 JOIN 语法将使您的查询更易于阅读和维护,(2) 外部查询只能看到子查询 SELECT 的字段,它不能“窥视”内部; (3) 目前尚不清楚为什么您甚至在看起来应该能够加入时使用子查询。
  • 换句话说,尝试从子查询外部访问子查询不 SELECT 的字段就像尝试从调用常规编程中的方法的代码中访问方法调用的局部变量语言。
  • 您需要详细说明您正在尝试做什么以及为什么。提供预期的结果。您的查询非常混乱,绝对可以简化。
  • 为了补充 Ryan 的评论,我继承了一个项目,在该项目中,以前的开发人员认为将大量查询的 WHERE 存储在单独的字符串变量中是一个好主意,就像这个问题一样。在使用它们的少数查询(有时只有一个)之前,它们往往被设置为大约三页代码。不用说我讨厌进入那个项目,我对那个开发者的看法显着下降。
  • 另外,明智地选择别名...您使用:countries_currencies a。为什么要让人们更加努力地将别名翻译成表格? 'cc'会这么糟糕吗?好的,要输入两个字符,但至少在阅读代码时更容易记住?通过countrylist b 发现问题。我可以建议您使用适当的布局(缩进)和别名编写代码。我怀疑你会自己发现代码的问题?

标签: mysql select where-clause


【解决方案1】:

正如我在 cmets 中所说,您可以从子查询外部访问的唯一字段是它选择的字段。也就是说,我真的不认为这个查询需要有任何子查询。 我的 PHP 有点弱,所以仔细检查字符串连接。

sql = "
SELECT cc.Currency_ISO3 AS value
   , cc.Rank AS ISSUE
   , coL.Name_fr AS PAYS
   , cuL.Name_fr AS DEVISE
   , CONCAT(cc.Currency_ISO, ' - ', coL.Name_fr, ' - ', cuL.Name_fr) AS label
FROM countries_currencies AS cc
INNER JOIN countrylist AS coL ON cc.Country_ISO3 = coL.Country_ISO3
INNER JOIN currencylist AS cuL ON cc.Currency_ISO3 = cuL.Currency_ISO3
".($onlyissuing ? "WHERE cc.Rank = 1" : "")
;

您会注意到,由于没有子查询,Rank 可以直接在 WHERE 中引用,因此它不需要包含在 SELECT 中(即使是,您也不能使用那个SELECT 中那个WHERE 的别名。)

【讨论】:

  • 谢谢,我已成功获得一个工作解决方案,其中未选择排名。但由于我是按照你的建议做的,我认为你的答案值得称赞,其中很好地包含了 $onlyissuing 参数
猜你喜欢
  • 2019-07-03
  • 1970-01-01
  • 1970-01-01
  • 2014-09-18
  • 2015-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-31
相关资源
最近更新 更多