1

我被困在我的表的内部连接方案中。你能帮我么?我在这里做错了什么?

这是我正在尝试做的场景:

我有计费和运输国家/州列,我试图用内部连接填充它们,但不知何故它不起作用。非常感谢你的帮助:

 $sql = $this->connection->query("SELECT * FROM ".TBL_USERS." 
    INNER JOIN ".TBL_USER_LEVEL." ON ".TBL_USERS.".userlevel = ".TBL_USER_LEVEL.".user_level_id 
    INNER JOIN ".TBL_COUNTRIES." ON ".TBL_USERS.".country OR ".TBL_USERS.".bcountry = ".TBL_COUNTRIES.".country_id
    INNER JOIN ".TBL_STATES." ON ".TBL_USERS.".states OR ".TBL_USERS.".bstates  = ".TBL_STATES.".states_id
    WHERE ".TBL_USERS.".username = '$username'");

我将查询更改为;我刚开始的错误是

PHP 致命错误:未捕获的异常 'PDOException' 带有消息'SQLSTATE [42000]:语法错误或访问冲突:1066 不是唯一的表/别名:'国家''

 $sql = $this->connection->query("SELECT * FROM ".TBL_USERS." 
    INNER JOIN ".TBL_USER_LEVEL." ON ".TBL_USERS.".userlevel = ".TBL_USER_LEVEL.".user_level_id 
    INNER JOIN ".TBL_COUNTRIES." ON ".TBL_USERS.".country = ".TBL_COUNTRIES.".country_id
    INNER JOIN ".TBL_COUNTRIES." ON ".TBL_USERS.".bcountry = ".TBL_COUNTRIES.".country_id
    INNER JOIN ".TBL_STATES." ON ".TBL_USERS.".states = ".TBL_STATES.".states_id

    INNER JOIN ".TBL_STATES." ON ".TBL_USERS.".bstates = ".TBL_STATES.".states_id

    WHERE ".TBL_USERS.".username = '$username'");

好的,这里的语法是正确的,非常感谢@Tiberiu-Ionuț Stan

$sql = $this->connection->query("SELECT * FROM ".TBL_USERS." 
    LEFT JOIN ".TBL_COUNTRIES." ON ".TBL_USERS.".country = ".TBL_COUNTRIES.".country_id 

   LEFT JOIN ".TBL_COUNTRIES." AS ".TBL_COUNTRIES."_b ON ".TBL_USERS.".bcountry=".TBL_COUNTRIES."_b.country_id

    INNER JOIN ".TBL_USER_LEVEL." ON ".TBL_USERS.".userlevel = ".TBL_USER_LEVEL.".user_level_id 
    LEFT JOIN ".TBL_STATES." ON ".TBL_USERS.".states = ".TBL_STATES.".states_id 

    LEFT JOIN ".TBL_STATES." AS ".TBL_STATES."_b ON ".TBL_USERS.".bstates=".TBL_STATES."_b.states_id


    WHERE ".TBL_USERS.".username = '$username'");
4

2 回答 2

1

JOIN table ON field OR another_field = expression除非引用field的是布尔类型,否则不能使用类似的构造。

您应该使用将返回布尔结果的构造,在您的情况下是这样的:

$sql = $this->connection->query("SELECT * FROM $TBL_USERS 
    JOIN $TBL_USER_LEVEL ON $TBL_USERS.userlevel = $TBL_USER_LEVEL.user_level_id 
    JOIN $TBL_COUNTRIES ON $TBL_USERS.country = $TBL_COUNTRIES.country_id
      OR $TBL_USERS.bcountry = $TBL_COUNTRIES.country_id
    JOIN $TBL_STATES ON $TBL_USERS.states = $TBL_STATES.states_id
      OR $TBL_USERS.bstates  = $TBL_STATES.states_id
    WHERE $TBL_USERS.username = '$username'");

我也直接使用了变量,否则很多字符串连接看起来很乱。您现在的查询对SQLi开放。

于 2012-04-26T20:33:34.027 回答
1

您可以在连接语句中使用 OR 和 AND。我一直都这样做。这是一个有效的方法:

  LEFT JOIN `currencies` ON (
   `currency_foreign`=`invoice_entry_amount_currency`
   AND
   `currency_reference`='".$strTransformToCurrency."'
   AND
   `currency_date`=FLOOR(`invoice_paid_timestamp`/86400)*86400
  )

问题在这里:

   INNER JOIN ".TBL_COUNTRIES." ON ".TBL_USERS.".country = ".TBL_COUNTRIES.".country_id
   INNER JOIN ".TBL_COUNTRIES." ON ".TBL_USERS.".bcountry = ".TBL_COUNTRIES.".country_id

MySQL 无法决定加入国家表的关系(因为 MySQL 认为 .country 和 .countryb 可能不同 - 所以加入后它不知道哪些列将被返回或用于条件和排序)。

试试这样:

  INNER JOIN ".TBL_COUNTRIES." ON ".TBL_USERS.".country = ".TBL_COUNTRIES.".country_id
  INNER JOIN ".TBL_COUNTRIES." AS ".TBL_COUNTRIES."_b ON ".TBL_USERS.".bcountry=".TBL_COUNTRIES."_b.country_id

如果您有非常大的表,请使用包含条件和排序的完整最终查询执行 EXPLAIN,以了解 MySQL 是否由于“TBL_USERS AS TBL_USERS_B”而进行表复制。

于 2012-04-26T20:50:10.867 回答