Как вы делаете несколько запросов в одной таблице, выбирая разные столбцы?
Если это вообще помогает … Все запросы имеют общий столбец в выбранной части инструкции 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 в одной таблице?
ПО ПУТИ … Я использую «комбинированный» в обоих моих примерах как мой последний запрос для отправки в базу данных.
Так что еще раз … Если в столбце нет совпадений, отобразите их как нулевые или просто полностью опустите ключ из результатов целиком.
Вы получаете неправильный «ключ» из-за оператора 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, и можете использовать это значение позже, чтобы понять, к чему принадлежит эта строка.