Объедините несколько MySQL-запросов в одной таблице в один

Как вы делаете несколько запросов в одной таблице, выбирая разные столбцы?

Если это вообще помогает … Все запросы имеют общий столбец в выбранной части инструкции SQL. Все они выбирают ID , затем следуют что-то конкретное.

Поэтому для каждого запроса требуется ID и одно из следующих post_name : post_name , post_title или post_excerpt .

Также, если это помогает упростить вещи. Я пытаюсь найти широкие совпадения и точные совпадения в этих столбцах.

Поэтому в моем примере я буду искать: «floor finish», «floor» или «finish» в следующих столбцах: post_name , post_title и post_excerpt . Все в одной таблице.

Я попытался выполнить это с UNION .

Вот мои вопросы:

 Array ( [broad] => Array ( [floor] => Array ( [slugs] => SELECT `ID`, `post_name` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_name` LIKE '%floor%' [titles] => SELECT `ID`, `post_title` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_title` LIKE '%floor%' [excerpts] => SELECT `ID`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_excerpt` LIKE '%floor%' ) [finish] => Array ( [slugs] => SELECT `ID`, `post_name` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_name` LIKE '%finish%' [titles] => SELECT `ID`, `post_title` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_title` LIKE '%finish%' [excerpts] => SELECT `ID`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_excerpt` LIKE '%finish%' ) ) [exact] => Array ( [slugs] => SELECT `ID`, `post_name` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_name` LIKE '%floor-finish%' [titles] => SELECT `ID`, `post_title` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_title` LIKE '%floor finish%' [excerpts] => SELECT `ID`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_excerpt` LIKE '%floor finish%' ) [combined] => ( SELECT `ID`, `post_name` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_name` LIKE '%floor-finish%' ) UNION ( SELECT `ID`, `post_name` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_name` LIKE '%floor%' ) UNION ( SELECT `ID`, `post_name` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_name` LIKE '%finish%' ) UNION ( SELECT `ID`, `post_title` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_title` LIKE '%floor finish%' ) UNION ( SELECT `ID`, `post_title` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_title` LIKE '%floor%' ) UNION ( SELECT `ID`, `post_title` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_title` LIKE '%finish%' ) UNION ( SELECT `ID`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_excerpt` LIKE '%floor finish%' ) UNION ( SELECT `ID`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_excerpt` LIKE '%floor%' ) UNION ( SELECT `ID`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND `post_excerpt` LIKE '%finish%' ) ) 

Однако приведенный выше результат интересен. Кажется, я получаю все правильные результаты, за исключением того, что ключ каждого значения результата (который должен быть именем столбца) всегда остается неизменным. Это всегда post_name даже если назначенное ему значение может быть post_title или post_excerpt .

Поэтому каждый результат имеет ID и post_name . В основном они неправильны, но значения кажутся точными.

Я также пробовал что-то вроде этого:

 Array ( [broad] => Array ( [floor] => SELECT `ID`, `post_name`, `post_title`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND ( `post_name` LIKE '%floor%' OR `post_title` LIKE '%floor%' OR `post_excerpt` LIKE '%floor' ) [finish] => SELECT `ID`, `post_name`, `post_title`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND ( `post_name` LIKE '%finish%' OR `post_title` LIKE '%finish%' OR `post_excerpt` LIKE '%finish%' ) ) [exact] => SELECT `ID`, `post_name`, `post_title`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND ( `post_name` LIKE '%floor-finish%' OR `post_title` LIKE '%floor finish%' OR `post_excerpt` LIKE '%floor finish%' ) [combined] => SELECT `ID`, `post_name`, `post_title`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND ( `post_name` LIKE '%floor-finish%' OR `post_title` LIKE '%floor finish%' OR `post_excerpt` LIKE '%floor finish%' ) UNION (SELECT `ID`, `post_name`, `post_title`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND ( `post_name` LIKE '%floor%' OR `post_title` LIKE '%floor%' OR `post_excerpt` LIKE '%floor%' )) UNION (SELECT `ID`, `post_name`, `post_title`, `post_excerpt` FROM tps_3_posts WHERE `post_status` = 'publish' AND ( `post_name` LIKE '%finish%' OR `post_title` LIKE '%finish%' OR `post_excerpt` LIKE '%finish%' )) ) ) 

Это больше похоже на то, что я пытаюсь выполнить. Я хочу, чтобы каждый результат имел ID , post_excerpt , post_slug и post_title . Если нет совпадений, отобразите их ключ с пустым значением или просто полностью не отобразите ключ.

Проблема со второй попыткой состоит в том, что требуется только совпадение в одном из трех желаемых столбцов. Поэтому, если он соответствует в post_excerpt и не где-то еще, он все равно вытащит значения из post_title и post_name . Таким образом, результаты становятся неточными.

Я прочитал несколько тем, что похоже на похожие вопросы, однако большинство из них не имеют реальных четких ответов … ИЛИ … Вопросы и ответы больше ориентированы на несколько запросов в таблицах SEPARATE.

Любые рекомендации или рекомендации по объединению нескольких запросов MySQL в одной таблице?

ПО ПУТИ … Я использую «комбинированный» в обоих моих примерах как мой последний запрос для отправки в базу данных.

Так что еще раз … Если в столбце нет совпадений, отобразите их как нулевые или просто полностью опустите ключ из результатов целиком.

Related of "Объедините несколько MySQL-запросов в одной таблице в один"

Вы получаете неправильный «ключ» из-за оператора UNION в своем запросе. У вас есть разные имена ключей, но совместимые типы столбцов между тремя разными столбцами – ваши объединенные запросы. Вместо того, чтобы бросать ошибку, механизм базы данных просто выбирает имя столбца из первого запроса и использует это для всех из них:

 id | post_name # <= column name in first query 1 | "my post" UNION id | post_title # <= column name is different, but type is compatible, so UNION succeeds 1 | "my post title" UNION id | post_excerpt # <= ditto 1 | "my post excerpt" 

приведет к:

 id | post_name # <= column name from first query 1 | "my post" 1 | "my post title" 1 | "my post excerpt" 

это то, что вы испытываете.

Вместо этого вы можете сделать что-то вроде:

 id | post_name | post_title | post_excerpt 1 | "my post" | null | null # <= deliberately select nulls for these columns in this query UNION id | post_name | post_title | post_excerpt 1 | null | "my post title" | null UNION id | post_name | post_title | post_excerpt 1 | null | null | "my post excerpt" 

Что даст вам результаты, такие как:

 id | post_name | post_title | post_excerpt 1 | "my post" | null | null 1 | null | "my post title" | null 1 | null | null | "my post excerpt" 

С вашей таблицей может показаться очень простая версия:

 SELECT ID, post_name, null AS post_title, null AS post_excerpt FROM tps_3_posts UNION SELECT ID, null AS post_name, post_title, null AS post_excerpt FROM tps_3_posts UNION SELECT ID, null AS post_name, null AS post_title, post_excerpt FROM tps_3_posts 

которые могут быть более полезными для того, что вы пытаетесь сделать. Вот SQLFiddle, если вы хотите увидеть его в действии.

Как я понял во втором случае, проблема в том, что только согласованный столбец должен иметь значение, а другие должны быть нулевыми. Для этого случая вы можете использовать инструкцию IF / ELSE или WHEN в SELECT. Идея заключается в том, что вы выбираете фактическое значение, значение этого столбца соответствует ожидаемому значению и null в противном случае.

Другое потенциальное решение – вы можете написать, например,

 SELECT `ID`, `post_name`, `post_title`, 'post_excerpt' 

Таким образом, вы выбираете строковое значение, являющееся критерием в инструкции WHERE, и можете использовать это значение позже, чтобы понять, к чему принадлежит эта строка.