MySQL UNION SELECT пока не найден? - PullRequest
3 голосов
/ 10 января 2012

Допустим, у меня есть таблица со столбцом "URL", где я храню URL-адреса, подобные этому

  • один / два

  • один / два / три

  • альфа / омега

И я хочу получить данные из базы данных для определенного URL-адреса, и если он не найден, я удаляю последнюю часть URL-адреса и снова выполняю поиск:

Пример:

У меня есть URL, как один / два / три / четыре / пять.

Я ищу "один / два / три / четыре / пять"

если не найден, снова выполнить поиск "один / два / три / четыре"

если не найден, снова искать "один / два / три"

если не найден, снова искать "один / два"

Я бы хотел что-то вроде:

SELECT * FROM db WHERE url=one/two/three/four/five

UNION

SELECT * FROM db WHERE url=one/two/three/four/five

UNION

SELECT * FROM db WHERE url=one/two/three/four

UNION

SELECT * FROM db WHERE url=one/two/three

UNION

SELECT * FROM db WHERE url=one/two

UNION

SELECT * FROM db WHERE url=one

но я хочу прекратить поиск, если строка найдена.

Возможно ли это, или я должен сделать это с разделенными запросами.

Спасибо за помощь.

Ответы [ 4 ]

3 голосов
/ 10 января 2012

Просто замените UNION на UNION ALL и добавьте LIMIT 1 в конце.

P.S. UNION ALL не будет иметь большого значения в этом конкретном примере, но полезно знать разницу: http://www.mysqlperformanceblog.com/2007/10/05/union-vs-union-all-performance/

3 голосов
/ 10 января 2012

Мне кажется, что это самый элегантный подход к вашему вопросу. Этот оператор является независимым путем глубины, и вам не нужно разделять постоянный URL в последующих выборках:

SELECT 
   * 
FROM 
   db 
WHERE 
   concat( 'one/two/three/four/five' , '/') like concat( url , '/%')
ORDER BY
   LENGTH (url) desc
LIMIT 1

Я проверил этот запрос в MySQL, также вы можете проверить его! (в синтаксисе MSSQL)

0 голосов
/ 10 января 2012

Вы можете использовать регулярное выражение для поиска в одном запросе, но он получит все строки:

SELECT * FROM db WHERE url REGEXP "^one((/two)|(/two/three)|(two/three/four)|(/two/three/four/five))?$"

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

SELECT * FROM db WHERE url REGEXP "^one((/two)|(/two/three)|(two/three/four)|(/two/three/four/five))?$" ORDER BY length(url) DESC LIMIT 1

. Это даст вам только первый возможный результат, но запрос внутри должен будетсначала получите все возможные результаты -> менее эффективно, но более компактно.

Надеюсь, это поможет!

0 голосов
/ 10 января 2012
Let's say I have table with column 'URL' whrere I store urls like this

one/two

one/two/three

alpha/omega

Не делайте этого, это ужасный дизайн, и доказательством является проблема, с которой вы сталкиваетесь при выполнении такого простого запроса; сохраняйте каждый URl на разных строках. Читайте о нормализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...