为什么空格会影响 MySQL Left Join 并返回 NULL 值?

发布于 2024-12-23 07:37:42 字数 13912 浏览 2 评论 0原文

我遇到了一个奇怪的问题,需要一些帮助来确定原因。到目前为止,我只能观察症状。它“似乎”正在发生的是,MySQL 根据我在第一个“LEFT JOIN”之前是否有换行符来执行不同的查询。

这是我的设置:

我正在 www.xeround.com 提供的 MySQL 数据库实例上运行查询。我正在使用 Kohana 框架,版本 3.0。我在 Lighttpd 上运行 PHP 5.3.3 FastCGI。我使用 MySQL 本机驱动程序编译了 PHP:

--with-mysql=mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd

我使用默认的 Kohana 3 MySQL 数据库驱动程序和 QueryBuilder。

我将跳过 PHP 代码并共享 SQL,因为这似乎是问题所在。 QueryBuilder 最终构建此查询:

SELECT `fieldreps`.`user_id` AS `fieldreps.user_id`, `fieldreps`.`availability_id` AS `fieldreps.availability_id`, `fieldreps`.`applicant_type` AS `fieldreps.applicant_type`, `fieldreps`.`license_number` AS `fieldreps.license_number`, `fieldreps`.`license_exp` AS `fieldreps.license_exp`, `fieldreps`.`license_state` AS `fieldreps.license_state`, `fieldreps`.`car` AS `fieldreps.car`, `fieldreps`.`authorized_worker` AS `fieldreps.authorized_worker`, `fieldreps`.`restrictions` AS `fieldreps.restrictions`, `fieldreps`.`night` AS `fieldreps.night`, `fieldreps`.`day` AS `fieldreps.day`, `fieldreps`.`longer` AS `fieldreps.longer`, `fieldreps`.`commitment` AS `fieldreps.commitment`, `fieldreps`.`travel_metro` AS `fieldreps.travel_metro`, `fieldreps`.`travel_states` AS `fieldreps.travel_states`, `fieldreps`.`big_employee` AS `fieldreps.big_employee`, `fieldreps`.`employed` AS `fieldreps.employed`, `fieldreps`.`retail` AS `fieldreps.retail`, `fieldreps`.`status` AS `fieldreps.status`, `fieldreps`.`start` AS `fieldreps.start`, `fieldreps`.`sales` AS `fieldreps.sales`, `fieldreps`.`study` AS `fieldreps.study`, `fieldreps`.`relevant` AS `fieldreps.relevant`, `fieldreps`.`experience` AS `fieldreps.experience`, `fieldreps`.`claims` AS `fieldreps.claims`, `fieldreps`.`education` AS `fieldreps.education`, `fieldreps`.`degree_details` AS `fieldreps.degree_details`, `fieldreps`.`degree_institution` AS `fieldreps.degree_institution`, `fieldreps`.`other_training` AS `fieldreps.other_training`, `fieldreps`.`jobs` AS `fieldreps.jobs`, `fieldreps`.`current_training` AS `fieldreps.current_training`, `fieldreps`.`interested` AS `fieldreps.interested`, `fieldreps`.`achievements` AS `fieldreps.achievements`, `fieldreps`.`passions` AS `fieldreps.passions`, `fieldreps`.`ambitions` AS `fieldreps.ambitions`, `fieldreps`.`max_travel_time` AS `fieldreps.max_travel_time`, `fieldreps`.`creation_time` AS `fieldreps.creation_time`, `fieldreps`.`resume` AS `fieldreps.resume`, `users`.`user_id` AS `users.user_id`, `users`.`email` AS `users.email`, `users`.`name` AS `users.name`, `users`.`password` AS `users.password`, `users`.`given_name` AS `users.given_name`, `users`.`title` AS `users.title`, `users`.`nationality` AS `users.nationality`, `availabilities`.`availability_id` AS `availabilities.availability_id`, `availabilities`.`fieldrep_id` AS `availabilities.fieldrep_id`, `availabilities`.`mon_start` AS `availabilities.mon_start`, `availabilities`.`mon_end` AS `availabilities.mon_end`, `availabilities`.`tue_start` AS `availabilities.tue_start`, `availabilities`.`tue_end` AS `availabilities.tue_end`, `availabilities`.`wed_start` AS `availabilities.wed_start`, `availabilities`.`wed_end` AS `availabilities.wed_end`, `availabilities`.`thur_start` AS `availabilities.thur_start`, `availabilities`.`thur_end` AS `availabilities.thur_end`, `availabilities`.`fri_start` AS `availabilities.fri_start`, `availabilities`.`fri_end` AS `availabilities.fri_end`, `availabilities`.`sat_start` AS `availabilities.sat_start`, `availabilities`.`sat_end` AS `availabilities.sat_end`, `availabilities`.`sun_start` AS `availabilities.sun_start`, `availabilities`.`sun_end` AS `availabilities.sun_end` FROM `fieldreps` AS `fieldreps` LEFT JOIN `users` ON (`fieldreps`.`user_id` = `users`.`user_id`) LEFT JOIN `availabilities` ON (`fieldreps`.`availability_id` = `availabilities`.`availability_id`)

返回如下结果:(我删除了从 Fieldreps 表返回的大部分字段,以使其简短且不那么个人化。)

[0] => Array
    (
        [fieldreps.user_id] => 1f01f4c2-43fd-550d-a53d-1f191786ebad
        [fieldreps.availability_id] => e31b0773-ecba-41d1-8ebb-7ac718496456
        [fieldreps.car] => Yes
        [fieldreps.authorized_worker] => Yes
        [fieldreps.restrictions] => Has Restrictions: No 
        [fieldreps.night] => Yes
        [fieldreps.day] => Yes
        [fieldreps.longer] => Yes
        [users.user_id] => 1f01f4c2-43fd-550d-a53d-1f191786ebad
        [users.email] => [email protected]
        [users.name] => Jones
        [users.password] =>
        [users.given_name] => Fred
        [users.title] => Miss
        [users.nationality] => 
        [availabilities.availability_id] => 
        [availabilities.fieldrep_id] => 
        [availabilities.mon_start] => 
        [availabilities.mon_end] => 
        [availabilities.tue_start] => 
        [availabilities.tue_end] => 
        [availabilities.wed_start] => 
        [availabilities.wed_end] => 
        [availabilities.thur_start] => 
        [availabilities.thur_end] => 
        [availabilities.fri_start] => 
        [availabilities.fri_end] => 
        [availabilities.sat_start] => 
        [availabilities.sat_end] => 
        [availabilities.sun_start] => 
        [availabilities.sun_end] => 
    )
[1] => Array
    (
        [fieldreps.user_id] => 812c3a9f-d7d8-565a-a886-1b182753dd41
        [fieldreps.availability_id] => 
        [fieldreps.car] => 1
        [fieldreps.authorized_worker] => 1
        [fieldreps.restrictions] => 
        [fieldreps.night] => 1
        [fieldreps.day] => 1
        [fieldreps.longer] => 1
        [users.user_id] => 812c3a9f-d7d8-565a-a886-1b182753dd41
        [users.email] => [email protected]
        [users.name] => Smith
        [users.password] => 
        [users.given_name] => Jill 
        [users.title] => 
        [users.nationality] => 
        [availabilities.availability_id] => 
        [availabilities.fieldrep_id] => 
        [availabilities.mon_start] => 
        [availabilities.mon_end] => 
        [availabilities.tue_start] => 
        [availabilities.tue_end] => 
        [availabilities.wed_start] => 
        [availabilities.wed_end] => 
        [availabilities.thur_start] => 
        [availabilities.thur_end] => 
        [availabilities.fri_start] => 
        [availabilities.fri_end] => 
        [availabilities.sat_start] => 
        [availabilities.sat_end] => 
        [availabilities.sun_start] => 
        [availabilities.sun_end] => 

但是,当我在第一个 LEFT JOIN 之前插入换行符时,像这样:

SELECT `fieldreps`.`user_id` AS `fieldreps.user_id`, `fieldreps`.`availability_id` AS `fieldreps.availability_id`, `fieldreps`.`applicant_type` AS `fieldreps.applicant_type`, `fieldreps`.`license_number` AS `fieldreps.license_number`, `fieldreps`.`license_exp` AS `fieldreps.license_exp`, `fieldreps`.`license_state` AS `fieldreps.license_state`, `fieldreps`.`car` AS `fieldreps.car`, `fieldreps`.`authorized_worker` AS `fieldreps.authorized_worker`, `fieldreps`.`restrictions` AS `fieldreps.restrictions`, `fieldreps`.`night` AS `fieldreps.night`, `fieldreps`.`day` AS `fieldreps.day`, `fieldreps`.`longer` AS `fieldreps.longer`, `fieldreps`.`commitment` AS `fieldreps.commitment`, `fieldreps`.`travel_metro` AS `fieldreps.travel_metro`, `fieldreps`.`travel_states` AS `fieldreps.travel_states`, `fieldreps`.`big_employee` AS `fieldreps.big_employee`, `fieldreps`.`employed` AS `fieldreps.employed`, `fieldreps`.`retail` AS `fieldreps.retail`, `fieldreps`.`status` AS `fieldreps.status`, `fieldreps`.`start` AS `fieldreps.start`, `fieldreps`.`sales` AS `fieldreps.sales`, `fieldreps`.`study` AS `fieldreps.study`, `fieldreps`.`relevant` AS `fieldreps.relevant`, `fieldreps`.`experience` AS `fieldreps.experience`, `fieldreps`.`claims` AS `fieldreps.claims`, `fieldreps`.`education` AS `fieldreps.education`, `fieldreps`.`degree_details` AS `fieldreps.degree_details`, `fieldreps`.`degree_institution` AS `fieldreps.degree_institution`, `fieldreps`.`other_training` AS `fieldreps.other_training`, `fieldreps`.`jobs` AS `fieldreps.jobs`, `fieldreps`.`current_training` AS `fieldreps.current_training`, `fieldreps`.`interested` AS `fieldreps.interested`, `fieldreps`.`achievements` AS `fieldreps.achievements`, `fieldreps`.`passions` AS `fieldreps.passions`, `fieldreps`.`ambitions` AS `fieldreps.ambitions`, `fieldreps`.`max_travel_time` AS `fieldreps.max_travel_time`, `fieldreps`.`creation_time` AS `fieldreps.creation_time`, `fieldreps`.`resume` AS `fieldreps.resume`, `users`.`user_id` AS `users.user_id`, `users`.`email` AS `users.email`, `users`.`name` AS `users.name`, `users`.`password` AS `users.password`, `users`.`given_name` AS `users.given_name`, `users`.`title` AS `users.title`, `users`.`nationality` AS `users.nationality`, `availabilities`.`availability_id` AS `availabilities.availability_id`, `availabilities`.`fieldrep_id` AS `availabilities.fieldrep_id`, `availabilities`.`mon_start` AS `availabilities.mon_start`, `availabilities`.`mon_end` AS `availabilities.mon_end`, `availabilities`.`tue_start` AS `availabilities.tue_start`, `availabilities`.`tue_end` AS `availabilities.tue_end`, `availabilities`.`wed_start` AS `availabilities.wed_start`, `availabilities`.`wed_end` AS `availabilities.wed_end`, `availabilities`.`thur_start` AS `availabilities.thur_start`, `availabilities`.`thur_end` AS `availabilities.thur_end`, `availabilities`.`fri_start` AS `availabilities.fri_start`, `availabilities`.`fri_end` AS `availabilities.fri_end`, `availabilities`.`sat_start` AS `availabilities.sat_start`, `availabilities`.`sat_end` AS `availabilities.sat_end`, `availabilities`.`sun_start` AS `availabilities.sun_start`, `availabilities`.`sun_end` AS `availabilities.sun_end` FROM `fieldreps` AS `fieldreps` 
LEFT JOIN `users` ON (`fieldreps`.`user_id` = `users`.`user_id`) LEFT JOIN `availabilities` ON (`fieldreps`.`availability_id` = `availabilities`.`availability_id`)

我现在得到了我想要的结果:

[0] => Array
    (
        [fieldreps.user_id] => 1f01f4c2-43fd-550d-a53d-1f191786ebad
        [fieldreps.availability_id] => e31b0773-ecba-41d1-8ebb-7ac718496456
        [fieldreps.car] => Yes
        [fieldreps.authorized_worker] => Yes
        [fieldreps.restrictions] => Has Restrictions: No 
        [fieldreps.night] => Yes
        [fieldreps.day] => Yes
        [fieldreps.longer] => Yes
        [users.user_id] => 1f01f4c2-43fd-550d-a53d-1f191786ebad
        [users.email] => [email protected]
        [users.name] => Jones
        [users.password] =>
        [users.given_name] => Fred
        [users.title] => Miss
        [users.nationality] => 
        [availabilities.availability_id] => e31b0773-ecba-41d1-8ebb-7ac718496456
        [availabilities.fieldrep_id] => 1f01f4c2-43fd-550d-a53d-1f191786ebad
        [availabilities.mon_start] => 540
        [availabilities.mon_end] => 1020
        [availabilities.tue_start] => 540
        [availabilities.tue_end] => 1020
        [availabilities.wed_start] => 540
        [availabilities.wed_end] => 1020
        [availabilities.thur_start] => 540
        [availabilities.thur_end] => 1020
        [availabilities.fri_start] => 540
        [availabilities.fri_end] => 1020
        [availabilities.sat_start] => 
        [availabilities.sat_end] => 
        [availabilities.sun_start] => 
        [availabilities.sun_end] => 
    )
[1] => Array
    (
        [fieldreps.user_id] => 812c3a9f-d7d8-565a-a886-1b182753dd41
        [fieldreps.availability_id] => 
        [fieldreps.car] => 1
        [fieldreps.authorized_worker] => 1
        [fieldreps.restrictions] => 
        [fieldreps.night] => 1
        [fieldreps.day] => 1
        [fieldreps.longer] => 1
        [users.user_id] => 812c3a9f-d7d8-565a-a886-1b182753dd41
        [users.email] => [email protected]
        [users.name] => Smith
        [users.password] => 
        [users.given_name] => Jill 
        [users.title] => 
        [users.nationality] => 
        [availabilities.availability_id] => 
        [availabilities.fieldrep_id] => 
        [availabilities.mon_start] => 
        [availabilities.mon_end] => 
        [availabilities.tue_start] => 
        [availabilities.tue_end] => 
        [availabilities.wed_start] => 
        [availabilities.wed_end] => 
        [availabilities.thur_start] => 
        [availabilities.thur_end] => 
        [availabilities.fri_start] => 
        [availabilities.fri_end] => 
        [availabilities.sat_start] => 
        [availabilities.sat_end] => 
        [availabilities.sun_start] => 
        [availabilities.sun_end] => 

请注意,Users 表上的 LEFT JOIN 在这两种情况下都可以正常工作。我还尝试在第二个 LEFT JOIN 之前添加换行符,而不是第一个。同样不想要的结果。我能找到的唯一解决办法是在第一个 LEFT JOIN 前面放置一个换行符。由 QueryBuilder 构建并发送到 MySQL 的查询始终是长的、单行、最小空白字符串...没有换行符!这是我第一次遇到这个问题。我简直不敢相信需要在第一个 LEFT JOIN 之前放置换行符。

我的问题归结为以下几点:

  1. 这应该是这样发生的吗? (空格影响查询结果)
  2. 获得我想要的结果的最佳方法是什么。

我不是 SQL 专家,否则我可能不需要问这个问题。我确信有一些事情我忽略了。

谢谢你,

乔纳森

I am having an odd issue and need some help determining the cause. So far, I have only been able to observe the symptoms. What it "seems" is happening is that MySQL is executing the query different based on whether or not I have a newline character before my first "LEFT JOIN".

Here is my setup:

I am running queries on a MySQL Database instance provided by www.xeround.com. I am using the Kohana framework, version 3.0. I am running PHP 5.3.3 FastCGI on Lighttpd. I compiled PHP with the MySQL Native Driver:

--with-mysql=mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd

I am using the default Kohana 3 MySQL Database Driver and QueryBuilder.

I am going to skip the PHP code and share the SQL since that seems to be the issue. The QueryBuilder ends up building this query:

SELECT `fieldreps`.`user_id` AS `fieldreps.user_id`, `fieldreps`.`availability_id` AS `fieldreps.availability_id`, `fieldreps`.`applicant_type` AS `fieldreps.applicant_type`, `fieldreps`.`license_number` AS `fieldreps.license_number`, `fieldreps`.`license_exp` AS `fieldreps.license_exp`, `fieldreps`.`license_state` AS `fieldreps.license_state`, `fieldreps`.`car` AS `fieldreps.car`, `fieldreps`.`authorized_worker` AS `fieldreps.authorized_worker`, `fieldreps`.`restrictions` AS `fieldreps.restrictions`, `fieldreps`.`night` AS `fieldreps.night`, `fieldreps`.`day` AS `fieldreps.day`, `fieldreps`.`longer` AS `fieldreps.longer`, `fieldreps`.`commitment` AS `fieldreps.commitment`, `fieldreps`.`travel_metro` AS `fieldreps.travel_metro`, `fieldreps`.`travel_states` AS `fieldreps.travel_states`, `fieldreps`.`big_employee` AS `fieldreps.big_employee`, `fieldreps`.`employed` AS `fieldreps.employed`, `fieldreps`.`retail` AS `fieldreps.retail`, `fieldreps`.`status` AS `fieldreps.status`, `fieldreps`.`start` AS `fieldreps.start`, `fieldreps`.`sales` AS `fieldreps.sales`, `fieldreps`.`study` AS `fieldreps.study`, `fieldreps`.`relevant` AS `fieldreps.relevant`, `fieldreps`.`experience` AS `fieldreps.experience`, `fieldreps`.`claims` AS `fieldreps.claims`, `fieldreps`.`education` AS `fieldreps.education`, `fieldreps`.`degree_details` AS `fieldreps.degree_details`, `fieldreps`.`degree_institution` AS `fieldreps.degree_institution`, `fieldreps`.`other_training` AS `fieldreps.other_training`, `fieldreps`.`jobs` AS `fieldreps.jobs`, `fieldreps`.`current_training` AS `fieldreps.current_training`, `fieldreps`.`interested` AS `fieldreps.interested`, `fieldreps`.`achievements` AS `fieldreps.achievements`, `fieldreps`.`passions` AS `fieldreps.passions`, `fieldreps`.`ambitions` AS `fieldreps.ambitions`, `fieldreps`.`max_travel_time` AS `fieldreps.max_travel_time`, `fieldreps`.`creation_time` AS `fieldreps.creation_time`, `fieldreps`.`resume` AS `fieldreps.resume`, `users`.`user_id` AS `users.user_id`, `users`.`email` AS `users.email`, `users`.`name` AS `users.name`, `users`.`password` AS `users.password`, `users`.`given_name` AS `users.given_name`, `users`.`title` AS `users.title`, `users`.`nationality` AS `users.nationality`, `availabilities`.`availability_id` AS `availabilities.availability_id`, `availabilities`.`fieldrep_id` AS `availabilities.fieldrep_id`, `availabilities`.`mon_start` AS `availabilities.mon_start`, `availabilities`.`mon_end` AS `availabilities.mon_end`, `availabilities`.`tue_start` AS `availabilities.tue_start`, `availabilities`.`tue_end` AS `availabilities.tue_end`, `availabilities`.`wed_start` AS `availabilities.wed_start`, `availabilities`.`wed_end` AS `availabilities.wed_end`, `availabilities`.`thur_start` AS `availabilities.thur_start`, `availabilities`.`thur_end` AS `availabilities.thur_end`, `availabilities`.`fri_start` AS `availabilities.fri_start`, `availabilities`.`fri_end` AS `availabilities.fri_end`, `availabilities`.`sat_start` AS `availabilities.sat_start`, `availabilities`.`sat_end` AS `availabilities.sat_end`, `availabilities`.`sun_start` AS `availabilities.sun_start`, `availabilities`.`sun_end` AS `availabilities.sun_end` FROM `fieldreps` AS `fieldreps` LEFT JOIN `users` ON (`fieldreps`.`user_id` = `users`.`user_id`) LEFT JOIN `availabilities` ON (`fieldreps`.`availability_id` = `availabilities`.`availability_id`)

Which returns a result like this:(I removed most of the fields returned from the Fieldreps table to keep it short and less personal.)

[0] => Array
    (
        [fieldreps.user_id] => 1f01f4c2-43fd-550d-a53d-1f191786ebad
        [fieldreps.availability_id] => e31b0773-ecba-41d1-8ebb-7ac718496456
        [fieldreps.car] => Yes
        [fieldreps.authorized_worker] => Yes
        [fieldreps.restrictions] => Has Restrictions: No 
        [fieldreps.night] => Yes
        [fieldreps.day] => Yes
        [fieldreps.longer] => Yes
        [users.user_id] => 1f01f4c2-43fd-550d-a53d-1f191786ebad
        [users.email] => [email protected]
        [users.name] => Jones
        [users.password] =>
        [users.given_name] => Fred
        [users.title] => Miss
        [users.nationality] => 
        [availabilities.availability_id] => 
        [availabilities.fieldrep_id] => 
        [availabilities.mon_start] => 
        [availabilities.mon_end] => 
        [availabilities.tue_start] => 
        [availabilities.tue_end] => 
        [availabilities.wed_start] => 
        [availabilities.wed_end] => 
        [availabilities.thur_start] => 
        [availabilities.thur_end] => 
        [availabilities.fri_start] => 
        [availabilities.fri_end] => 
        [availabilities.sat_start] => 
        [availabilities.sat_end] => 
        [availabilities.sun_start] => 
        [availabilities.sun_end] => 
    )
[1] => Array
    (
        [fieldreps.user_id] => 812c3a9f-d7d8-565a-a886-1b182753dd41
        [fieldreps.availability_id] => 
        [fieldreps.car] => 1
        [fieldreps.authorized_worker] => 1
        [fieldreps.restrictions] => 
        [fieldreps.night] => 1
        [fieldreps.day] => 1
        [fieldreps.longer] => 1
        [users.user_id] => 812c3a9f-d7d8-565a-a886-1b182753dd41
        [users.email] => [email protected]
        [users.name] => Smith
        [users.password] => 
        [users.given_name] => Jill 
        [users.title] => 
        [users.nationality] => 
        [availabilities.availability_id] => 
        [availabilities.fieldrep_id] => 
        [availabilities.mon_start] => 
        [availabilities.mon_end] => 
        [availabilities.tue_start] => 
        [availabilities.tue_end] => 
        [availabilities.wed_start] => 
        [availabilities.wed_end] => 
        [availabilities.thur_start] => 
        [availabilities.thur_end] => 
        [availabilities.fri_start] => 
        [availabilities.fri_end] => 
        [availabilities.sat_start] => 
        [availabilities.sat_end] => 
        [availabilities.sun_start] => 
        [availabilities.sun_end] => 

However, when I insert a newline character immediately before the first LEFT JOIN, like this:

SELECT `fieldreps`.`user_id` AS `fieldreps.user_id`, `fieldreps`.`availability_id` AS `fieldreps.availability_id`, `fieldreps`.`applicant_type` AS `fieldreps.applicant_type`, `fieldreps`.`license_number` AS `fieldreps.license_number`, `fieldreps`.`license_exp` AS `fieldreps.license_exp`, `fieldreps`.`license_state` AS `fieldreps.license_state`, `fieldreps`.`car` AS `fieldreps.car`, `fieldreps`.`authorized_worker` AS `fieldreps.authorized_worker`, `fieldreps`.`restrictions` AS `fieldreps.restrictions`, `fieldreps`.`night` AS `fieldreps.night`, `fieldreps`.`day` AS `fieldreps.day`, `fieldreps`.`longer` AS `fieldreps.longer`, `fieldreps`.`commitment` AS `fieldreps.commitment`, `fieldreps`.`travel_metro` AS `fieldreps.travel_metro`, `fieldreps`.`travel_states` AS `fieldreps.travel_states`, `fieldreps`.`big_employee` AS `fieldreps.big_employee`, `fieldreps`.`employed` AS `fieldreps.employed`, `fieldreps`.`retail` AS `fieldreps.retail`, `fieldreps`.`status` AS `fieldreps.status`, `fieldreps`.`start` AS `fieldreps.start`, `fieldreps`.`sales` AS `fieldreps.sales`, `fieldreps`.`study` AS `fieldreps.study`, `fieldreps`.`relevant` AS `fieldreps.relevant`, `fieldreps`.`experience` AS `fieldreps.experience`, `fieldreps`.`claims` AS `fieldreps.claims`, `fieldreps`.`education` AS `fieldreps.education`, `fieldreps`.`degree_details` AS `fieldreps.degree_details`, `fieldreps`.`degree_institution` AS `fieldreps.degree_institution`, `fieldreps`.`other_training` AS `fieldreps.other_training`, `fieldreps`.`jobs` AS `fieldreps.jobs`, `fieldreps`.`current_training` AS `fieldreps.current_training`, `fieldreps`.`interested` AS `fieldreps.interested`, `fieldreps`.`achievements` AS `fieldreps.achievements`, `fieldreps`.`passions` AS `fieldreps.passions`, `fieldreps`.`ambitions` AS `fieldreps.ambitions`, `fieldreps`.`max_travel_time` AS `fieldreps.max_travel_time`, `fieldreps`.`creation_time` AS `fieldreps.creation_time`, `fieldreps`.`resume` AS `fieldreps.resume`, `users`.`user_id` AS `users.user_id`, `users`.`email` AS `users.email`, `users`.`name` AS `users.name`, `users`.`password` AS `users.password`, `users`.`given_name` AS `users.given_name`, `users`.`title` AS `users.title`, `users`.`nationality` AS `users.nationality`, `availabilities`.`availability_id` AS `availabilities.availability_id`, `availabilities`.`fieldrep_id` AS `availabilities.fieldrep_id`, `availabilities`.`mon_start` AS `availabilities.mon_start`, `availabilities`.`mon_end` AS `availabilities.mon_end`, `availabilities`.`tue_start` AS `availabilities.tue_start`, `availabilities`.`tue_end` AS `availabilities.tue_end`, `availabilities`.`wed_start` AS `availabilities.wed_start`, `availabilities`.`wed_end` AS `availabilities.wed_end`, `availabilities`.`thur_start` AS `availabilities.thur_start`, `availabilities`.`thur_end` AS `availabilities.thur_end`, `availabilities`.`fri_start` AS `availabilities.fri_start`, `availabilities`.`fri_end` AS `availabilities.fri_end`, `availabilities`.`sat_start` AS `availabilities.sat_start`, `availabilities`.`sat_end` AS `availabilities.sat_end`, `availabilities`.`sun_start` AS `availabilities.sun_start`, `availabilities`.`sun_end` AS `availabilities.sun_end` FROM `fieldreps` AS `fieldreps` 
LEFT JOIN `users` ON (`fieldreps`.`user_id` = `users`.`user_id`) LEFT JOIN `availabilities` ON (`fieldreps`.`availability_id` = `availabilities`.`availability_id`)

I now get the result I want:

[0] => Array
    (
        [fieldreps.user_id] => 1f01f4c2-43fd-550d-a53d-1f191786ebad
        [fieldreps.availability_id] => e31b0773-ecba-41d1-8ebb-7ac718496456
        [fieldreps.car] => Yes
        [fieldreps.authorized_worker] => Yes
        [fieldreps.restrictions] => Has Restrictions: No 
        [fieldreps.night] => Yes
        [fieldreps.day] => Yes
        [fieldreps.longer] => Yes
        [users.user_id] => 1f01f4c2-43fd-550d-a53d-1f191786ebad
        [users.email] => [email protected]
        [users.name] => Jones
        [users.password] =>
        [users.given_name] => Fred
        [users.title] => Miss
        [users.nationality] => 
        [availabilities.availability_id] => e31b0773-ecba-41d1-8ebb-7ac718496456
        [availabilities.fieldrep_id] => 1f01f4c2-43fd-550d-a53d-1f191786ebad
        [availabilities.mon_start] => 540
        [availabilities.mon_end] => 1020
        [availabilities.tue_start] => 540
        [availabilities.tue_end] => 1020
        [availabilities.wed_start] => 540
        [availabilities.wed_end] => 1020
        [availabilities.thur_start] => 540
        [availabilities.thur_end] => 1020
        [availabilities.fri_start] => 540
        [availabilities.fri_end] => 1020
        [availabilities.sat_start] => 
        [availabilities.sat_end] => 
        [availabilities.sun_start] => 
        [availabilities.sun_end] => 
    )
[1] => Array
    (
        [fieldreps.user_id] => 812c3a9f-d7d8-565a-a886-1b182753dd41
        [fieldreps.availability_id] => 
        [fieldreps.car] => 1
        [fieldreps.authorized_worker] => 1
        [fieldreps.restrictions] => 
        [fieldreps.night] => 1
        [fieldreps.day] => 1
        [fieldreps.longer] => 1
        [users.user_id] => 812c3a9f-d7d8-565a-a886-1b182753dd41
        [users.email] => [email protected]
        [users.name] => Smith
        [users.password] => 
        [users.given_name] => Jill 
        [users.title] => 
        [users.nationality] => 
        [availabilities.availability_id] => 
        [availabilities.fieldrep_id] => 
        [availabilities.mon_start] => 
        [availabilities.mon_end] => 
        [availabilities.tue_start] => 
        [availabilities.tue_end] => 
        [availabilities.wed_start] => 
        [availabilities.wed_end] => 
        [availabilities.thur_start] => 
        [availabilities.thur_end] => 
        [availabilities.fri_start] => 
        [availabilities.fri_end] => 
        [availabilities.sat_start] => 
        [availabilities.sat_end] => 
        [availabilities.sun_start] => 
        [availabilities.sun_end] => 

Notice that the LEFT JOIN on the Users table works fine in both scenarios. I also tried adding the newline before the second LEFT JOIN, instead of the first. Same unwanted result. The only thing that I can find to fix it is placing a newline in front of the first LEFT JOIN. The queries that are built by QueryBuilder and sent to MySQL are always long, single-line, minimum whitespace strings...no newlines! This is the first time I have had this issue. I just can't believe there would be a requirement to place a newline before the first LEFT JOIN.

My question boils down to these points:

  1. Is this supposed be happening this way? (Whitespace effecting the query result)
  2. What is the best way to go about getting the result I want.

I am not an SQL expert, otherwise I would probably not need to ask this question. I am sure there is something I am overlooking.

Thank you,

Jonathan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦幻的味道 2024-12-30 07:37:42

我的问题就在我面前,就像我想象的那样:

索引

我无意中在availities.fieldrep_id上创建了两个索引,而架构其余部分的索引充其量是劣质的。

我使用了 EXPLAIN,它表明它没有对三个连接中的两个使用索引。我清理了索引,现在每次都效果很好。

另外,我想我明白了为什么换行符会改变查询。如果我一遍又一遍地运行查询,我会看到它在给定的示例之间切换,无论是否添加换行符。我假设 MySQL 有一些重复查询的缓存。我敢打赌,换行符足以触发它忽略缓存的版本,因此它有时会给我想要的结果。

无论如何,问题出在指数上。其他一切都只是一个症状。

也许这会帮助某人节省一些时间。

My issue was right in front of me like I thought:

Indices

I had inadvertently created two indices on availabilities.fieldrep_id, and the indices on the rest of the schema were, shoddy-at best.

I used EXPLAIN which indicated it was not using an index for 2 of the three joins. I cleaned up my indices and now it works great, everytime.

Also, I think I figured out why the newline would change the query. If I ran the query over and over I would see it switch between the examples given, regardless of adding the newline or not. I am assuming that MySQL has some caching for repeat queries. I bet that the newline was enough to trigger it to ignore the cached version, hence it would sometimes give me the desired result.

Regardless, the issue was with indices. Everything else was just a symptom.

Maybe this will help someone save a bit of time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文