MySQL内连接一列上的两列

时间:2012-04-26 20:19:29

标签: php mysql inner-join

我坚持使用表格的内连接方案。你能帮我么?我在这里做错了什么?

以下是我正在尝试的方案:

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

 $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不唯一的表/别名:'countries''in

 $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'");

2 个答案:

答案 0 :(得分: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开放了。

答案 1 :(得分: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无法决定加入countries表的关系(因为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”。