Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Выборка из 2-х таблиц даже при том, что для полей одной таблицы может не существовать полей другой

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
SkaN
Отправлено: 29 Августа, 2014 - 07:17:46
Post Id



Гость


Покинул форум
Сообщений всего: 103
Дата рег-ции: Март 2011  


Помог: 0 раз(а)




В заголовке очень сумбурно описал, потому что я не очень понимаю, как это описать лучше. Вот расширенное:
Есть две таблицы: одна с постами, а в другой есть все данные для постов (это Wordpress и его таблицы _posts и _postmeta). Во всех данных структура такая: entry_id, post_id, meta_key, meta_value. Для некоторых записей из таблицы _posts есть запись в таблице _postmeta, которая соответствует условию
CODE (SQL):
скопировать код в буфер обмена
  1. WHERE `_posts`.`post_id` = `_postmeta`.`post_id` AND `_postmeta`.`meta_key` = '_yourls'

Но в то же время для некоторых такой записи просто не существует, даже со значением NULL. То есть по запросу получается вытащить либо те посты, для которых есть _yourls, либо те, для которых нет. Я решил это UNION'ом, получилось так:
CODE (SQL):
скопировать код в буфер обмена
  1. SET @start='2014-08-27 21:32:00';
  2. SELECT * FROM (
  3.     SELECT `site_posts`.`ID` AS `id`, `site_posts`.`post_author` AS `author`, `site_posts`.`post_title` AS `title`, `site_posts`.`post_date_gmt` AS `date`, `site_postmeta`.`meta_value` AS `url`
  4.     FROM `site_posts`
  5.     LEFT OUTER JOIN `site_postmeta` ON `site_postmeta`.`post_id` = `site_posts`.`ID`
  6.     WHERE `post_date_gmt` > @start
  7.     AND `site_postmeta`.`meta_key` = '_yourls_url'
  8.     AND `post_type` = 'post'
  9.     AND `post_status` = 'publish'
  10.     AND `site_posts`.`post_author` NOT IN (202, 224, 226, 201, 200, 225)
  11.  
  12. UNION DISTINCT
  13.  
  14.     SELECT `site_posts`.`ID` AS `id`, `site_posts`.`post_author` AS `author`, `site_posts`.`post_title` AS `title`, `site_posts`.`post_date_gmt` AS `date`, NULL AS `url`
  15.     FROM `site_posts`
  16.     WHERE `post_date_gmt` > @start
  17.     AND `post_type` = 'post'
  18.     AND `post_status` = 'publish'
  19.     AND `site_posts`.`post_author` NOT IN (202, 224, 226, 201, 200, 225)
  20.     AND NOT EXISTS (
  21.         SELECT * FROM `site_postmeta` WHERE `site_postmeta`.`post_id` = `site_posts`.`ID` AND `site_postmeta`.`meta_key` = '_yourls_url'
  22.     )
  23. ) AS `new_posts`
  24. GROUP BY `author`, `title`
  25. ORDER BY `date` DESC;

Но тут наступает некоторая задница, потому что пусть запрос отрабатывает красиво, возвращая один набор данных, но сам запрос не до конца оптимизирован и почти что не расширяем. Теперь вопросы:
Как мне можно сначала выбрать посты по одинаковым условиям из обоих запросов? Подозреваю, что тут мне помогут вложенные SELECT'ы.
Другой вопрос: как мне можно в один набор данных объединить посты, для которых есть _yourls и посты, для которых нет, так, чтобы, если _youls есть, то он выбирался, а если нет, чтобы на его месте был NULL?
Спасибо за старания понять мою писанину Радость
 
 Top
Мелкий Супермодератор
Отправлено: 29 Августа, 2014 - 07:22:59
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




left join


-----
PostgreSQL DBA
 
 Top
SkaN
Отправлено: 30 Августа, 2014 - 00:26:49
Post Id



Гость


Покинул форум
Сообщений всего: 103
Дата рег-ции: Март 2011  


Помог: 0 раз(а)




CODE (SQL):
скопировать код в буфер обмена
  1. SET @start='2014-08-27 21:32:00';
  2. SELECT `site_posts`.`ID` AS `id`, `site_posts`.`post_author` AS `author`, `site_posts`.`post_title` AS `title`, `site_posts`.`post_date_gmt` AS `date`, `site_postmeta`.`meta_value` AS `url`
  3. FROM `site_posts`
  4. LEFT JOIN `site_postmeta` ON `site_postmeta`.`post_id` = `site_posts`.`ID`
  5. WHERE `post_date_gmt` > @start
  6. AND `site_postmeta`.`meta_key` = '_yourls_url'
  7. AND `post_type` = 'post'
  8. AND `post_status` = 'publish'
  9. AND `site_posts`.`post_author` NOT IN (202, 224, 226, 201, 200, 225)

Сделал так, выбираются только те посты, для которых есть поле _yourls, те, для которых нет, не выбираются вообще.
 
 Top
SkaN
Отправлено: 30 Августа, 2014 - 03:34:12
Post Id



Гость


Покинул форум
Сообщений всего: 103
Дата рег-ции: Март 2011  


Помог: 0 раз(а)




CODE (SQL):
скопировать код в буфер обмена
  1. SELECT `site_posts`.`ID` AS `id`, `site_posts`.`post_author` AS `author`, `site_posts`.`post_title` AS `title`, `site_posts`.`post_date_gmt` AS `date`, `yourls`.`url` AS `url`
  2. FROM `site_posts`
  3. LEFT JOIN (
  4.     SELECT `post_id`, `meta_value` AS `url`
  5.     FROM `site_postmeta`
  6.     WHERE `meta_key` = '_yourls_url'
  7. ) AS `yourls` ON `yourls`.`post_id` = `id`
  8. WHERE `post_date_gmt` > '2014-08-25 21:32:00'
  9. AND `post_type` = 'post'
  10. AND `post_status` = 'publish'

Вот такое решение. Сделал встроенный запрос, чтобы изолировать условие WHERE `meta_key` = '_yourls_url'. Если его добавить в основной запрос, то возвращается только то, что имеет такое поле.
 
 Top
Мелкий Супермодератор
Отправлено: 30 Августа, 2014 - 10:52:48
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




CODE (SQL):
скопировать код в буфер обмена
  1. SELECT `site_posts`.`ID` AS `id`, `site_posts`.`post_author` AS `author`, `site_posts`.`post_title` AS `title`, `site_posts`.`post_date_gmt` AS `date`, `site_postmeta`.`meta_value` AS `url`
  2. FROM `site_posts`
  3. LEFT JOIN `site_postmeta` ON `site_postmeta`.`post_id` = `site_posts`.`ID` AND `site_postmeta`.`meta_key` = '_yourls_url'
  4. WHERE `post_date_gmt` > @start
  5. AND `post_type` = 'post'
  6. AND `post_status` = 'publish'
  7. AND `site_posts`.`post_author` NOT IN (202, 224, 226, 201, 200, 225)


-----
PostgreSQL DBA
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Работа с СУБД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB