Intereting Posts
mysql & php: временные / виртуальные идентификаторы для результатов запроса? Как получить путь к двоичному файлу php на сервере, где он находится Удалить знак пунктуации с регулярным выражением? Как я могу использовать класс APP CakePHP для загрузки XML-файлов из URL-адреса? Получить родительский каталог запущенного скрипта Не удается получить .htaccess для работы на localhost Сортировка массива несколькими ключами в определенном порядке Как использовать механизм шаблонов PHP в Twig вместо синтаксиса Twig в Silex 2 Многотысячные сорта? Прохождение Laravel 4: исключение класса не найдено PHP. Внешний класс / библиотека доступен из apache, но не из phpunit wordpress, получить имена категорий для настраиваемого типа сообщений Вход с Amazon говорит, что пользователь не согласился, но у них есть – Alexa SMAPI Получить изображениеjpeg для правильного отображения php отправить электронное письмо с изображением

Получение результатов запроса из двух таблиц db, даже если вторая таблица не имеет соответствующих записей

Вот моя проблема: получение результатов запроса из двух таблиц db, даже если вторая таблица не имеет соответствующих записей.

Вот пример кода, который я использую в SQL

SELECT DISTINCT apps.id, apps.*, req.status FROM applications AS apps, requests AS req WHERE apps.id = {$app_id} 

Но проблема в том, что он не потянет приложения, у которых нет значения request.status / entry, так что вопросы: будет ли возможно изменить этот простой запрос, чтобы поднять результаты для всех приложений. * Строки, даже если там нет соответствующих запросов. Строка / запись?

EDIT BELLOW:

так вот мой новый запрос от обратной связи, которую я получил (это прекрасно работает)

 SELECT DISTINCT apps.*, req.status FROM applications AS apps LEFT JOIN requests AS req ON (req.app_id = apps.id AND req.uid = {$user_id}) WHERE apps.id = {$app_id} 

BUT: Когда я добавляю новое выражение в предложение where для фильтрации статуса запроса, я получаю ту же проблему, что и с неявным запросом, я не получаю результаты (запрос ниже)

 SELECT DISTINCT apps.*, req.status FROM applications AS apps LEFT JOIN requests AS req ON (req.app_id = apps.id AND req.uid = {$user_id}) WHERE apps.id = {$app_id} AND (req.status = 2 OR req.status = 5) 

ДРУГОЕ ИЗМЕНЕНИЕ

Вот обновленный код для просмотра. Теперь проблема заключается в том, что если я добавлю подзапрос, суб-запрос вытащит все строки, тогда значение NULL будет как значение для столбца состояния, но как только я добавлю состояние WHERE! = 2, он просто удалит все записи, не должно ли это иметь все строки с нулевым значением? потому что null явно! = 2.

 SELECT DISTINCT apps . * FROM (SELECT apps . *, req.status FROM appstore_app AS apps LEFT JOIN app_user_request AS req ON (req.uid = 187 AND req.appid = apps.appid) WHERE apps.appid > 0 AND apps.company_id = 122) AS apps WHERE apps.status != 2 ORDER BY apps.average_user_rating DESC 

ЗАВЕРШЕНИЕ

СПАСИБО ЗА ПОМОЩЬ!

Вот мой последний запрос, который работал для меня:

 SELECT apps.*, req.status FROM appstore_app AS apps LEFT JOIN app_user_request AS req ON (req.uid = {$user_id} AND req.appid = apps.appid AND (req.status IS NULL OR req.status != 2)) WHERE apps.appid > 0 AND apps.company_id = {$company_id} 

Solutions Collecting From Web of "Получение результатов запроса из двух таблиц db, даже если вторая таблица не имеет соответствующих записей"

ОП сказал:

BUT: Когда я добавляю новое выражение в предложение where для фильтрации статуса запроса, i> получаю ту же проблему, что и при неявном запросе, я не получаю результаты (запрос ниже)

 SELECT DISTINCT apps.*, req.status FROM applications apps LEFT JOIN requests req ON req.app_id = apps.id AND req.uid = {$user_id} WHERE apps.id = {$app_id} AND ( req.status = 2 OR req.status = 5 ) 

Проблема заключается в том, что предложение where фильтрует результаты, поэтому ваш тест на req.status из 2 или 5 выдает все, где req.status имеет значение null, потому что ни одна строка не соответствует табличным applications .

Общий, теоретический (поскольку ничто, кроме тривиальной реализации, никогда не будет делать что-либо подобное) порядок операций для оператора select :

  • Произведите полное декартово произведение каждой таблицы, указанной в предложении from .
  • Отфильтруйте это, применив указанные критерии join и исключив строки, которые не проходят указанные тесты.
  • Примените критерии фильтра, указанные в предложении where , удалив строки, которые не проходят указанные тесты.
  • Закажите результаты, установленные в выражениях, указанных в предложении group by , и разделите результаты, заданные на группы.
  • Свернуть каждую группу в одну строку, вычисляя значение всех указанных агрегатных функций.
  • Удалите все столбцы из набора результатов, которые не указаны в списке столбцов select операторов.
  • Закажите эти окончательные результаты, заданные столбцами / выражениями, указанными в предложении order by .

Вы можете сделать одну из двух вещей:

  • измените свой запрос, чтобы проверить значение nullity:

     where...( req.status is null OR req.status in (2,5) )... 
  • переместите тест против req.status в критерии соединения:

     left join requests req on req.app_id = apps.id and req.uid = {$user_id} and req.status in (2,5) 
 SELECT DISTINCT apps.*, req.status FROM applications AS apps LEFT JOIN requests AS req on req.app_id = apps.id WHERE apps.id = {$app_id} 

LEFT JOIN отобразит все ваши приложения, даже если соответствующие запросы отсутствуют.

 SELECT DISTINCT apps.id, apps.*, req.status FROM applications apps LEFT JOIN requests req ON req.? = applications.? WHERE apps.id = {$app_id} 

Вам нужно добавить столбец ( ? ), Который связывает обе таблицы вместе.

Вам нужно будет использовать явный LEFT JOIN следующим образом:

 SELECT DISTINCT apps.id, apps.*, req.status FROM applications AS apps LEFT JOIN requests AS req ON apps.whatever_field_relates = req.whatever_field_relates WHERE apps.id = {$app_id} 

Использование неявных JOINS, таких как FROM table1, table2 не является хорошей практикой IMO. Это затрудняет для других программистов понимание точной природы JOIN с первого взгляда без необходимости ссылаться на схему базы данных.

 SELECT DISTINCT app.*,req.status from applications apps left join request as req on req.appid = apps.id where apps.id ={$app_id} 

Выполнение левого соединения сделает трюк, я привык к синтаксису TSQL, но я уверен, что он будет работать в Mysql. Вам нужно указать идентификатор ваших приложений в обеих таблицах, чтобы иметь возможность присоединиться к ним.

В вашем запросе используется неявное перекрестное соединение, выбор данных из двух таблиц без указания способа связывания двух таблиц. То, что вы действительно хотите, – это левое соединение.

 SELECT DISTINCT apps.id, apps.*, req.status FROM applications AS apps LEFT JOIN requests AS req ON apps.id = req.apps_id /* Guessing on the relationship here */ WHERE apps.id = {$app_id} 

После правильного синтаксиса посмотрите, действительно ли DISTINCT необходим для этого запроса. Это может быть дорогостоящим издержками, которые могут быть устранены.

EDIT : следующий раздел добавляется в ответ на отредактированный вопрос.

Когда вы проверяете столбец LEFT JOINed ( req.status в вашем случае) в предложении WHERE, вы вынуждаете это соединение вести себя так, как если бы это был INNER JOIN. Вместо этого сделайте эти тесты частью условий соединения.

 SELECT DISTINCT apps.*, req.status FROM applications AS apps LEFT JOIN requests AS req ON (req.app_id = apps.id AND req.uid = {$user_id}) AND (req.status = 2 OR req.status = 5) WHERE apps.id = {$app_id}