возможно ли лимитировать JOIN ??

iamFake

Mind Of Liberty
возможно ли лимитировать JOIN ??

Здравствуйте.

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

Данный запрос делает требуемое за исключением ограничения в 3 записи из таблици two, как можно реализовать подобный лимит?

если в базе 1 категория - результат запроса будет содержать максимум 3 строки, если категорий 3 - то до 9 строк... реализация через UNION дает результат где сначала идут все строки результата первого запроса, затем второго... неудобно...

PHP:
SELECT `one`.`id`,`one`.`title`,`one`.`name`,`one`.`desc`,`two`.`title`
FROM `category` as `one` 
JOIN `board` as `two` ON `two`.`cat` = `one`.`id`
WHERE `one`.`active` = '1'
AND `one`.`parent` = '1'
спасибо
 

RUNET

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

друго выхода не пока не вижу.
 

iamFake

Mind Of Liberty
Почитал про вложенные запросы, нашел упоминание о возможности возврата "таблици" (A subquery can return a table (one or more rows of one or more columns)) в документации мускула, но не нашел там примера оного, из за чего "углубился" в JOIN синтакс, там и откопался "table_subquery" =) спасибо

PHP:
SELECT `one`.`id`,`one`.`title`,`one`.`name`,`one`.`desc`,`two`.`title` as `2title`,`two`.`id` as `tid`
FROM `category` as `one`  
JOIN 
(
    SELECT `id`,`cat`,`title` FROM `board` LIMIT 3
) as `two` ON `two`.`cat` = `one`.`id` 
WHERE `one`.`active` = '1' 
AND `one`.`parent` = '1'
 

Вурдалак

Продвинутый новичок
Автор оригинала: iamFake
Почитал про вложенные запросы, нашел упоминание о возможности возврата "таблици" (A subquery can return a table (one or more rows of one or more columns)) в документации мускула, но не нашел там примера оного, из за чего "углубился" в JOIN синтакс, там и откопался "table_subquery" =) спасибо

PHP:
SELECT `one`.`id`,`one`.`title`,`one`.`name`,`one`.`desc`,`two`.`title` as `2title`,`two`.`id` as `tid`
FROM `category` as `one`  
JOIN 
(
    SELECT `id`,`cat`,`title` FROM `board` LIMIT 3
) as `two` ON `two`.`cat` = `one`.`id` 
WHERE `one`.`active` = '1' 
AND `one`.`parent` = '1'
Даже если бы оно работало (LIMIT в subquery делать нельзя), то логика была бы не такая, какая тебе хотелась.
 

iamFake

Mind Of Liberty
Автор оригинала: Вурдалак
Даже если бы оно работало (LIMIT в subquery делать нельзя), то логика была бы не такая, какая тебе хотелась.
Все работает на ура... LIMIT разрешен в сабквери заисключением случаев если сабквери находится внутри IN/ALL/ANY/SOME, о чем говорит одна из ошибок в мускуле:

Unsupported subquery syntax:
ERROR 1235 (ER_NOT_SUPPORTED_YET)
SQLSTATE = 42000
Message = "This version of MySQL does not yet support
'LIMIT & IN/ALL/ANY/SOME subquery'"

This means that statements of the following form do not work yet:
SELECT * FROM t1 WHERE s1 IN (SELECT s2 FROM t2 ORDER BY s1 LIMIT 1)
 

Вурдалак

Продвинутый новичок
Автор оригинала: iamFake
Все работает на ура... LIMIT разрешен в сабквери заисключением случаев если сабквери находится внутри IN/ALL/ANY/SOME, о чем говорит одна из ошибок в мускуле:

Unsupported subquery syntax:
ERROR 1235 (ER_NOT_SUPPORTED_YET)
SQLSTATE = 42000
Message = "This version of MySQL does not yet support
'LIMIT & IN/ALL/ANY/SOME subquery'"

This means that statements of the following form do not work yet:
SELECT * FROM t1 WHERE s1 IN (SELECT s2 FROM t2 ORDER BY s1 LIMIT 1)
О, спасибо, действительно не знал. Но всё-таки, логика совсем не та, что хотелась. Я правильно понимаю, что ты хотел для каждой категории выводить по три 3 записи из другой таблицы? Сейчас же просто происходит перемножение 2-х таблиц: категорий и урезанной (до трёх записей) другой таблицы.
 

iamFake

Mind Of Liberty
да, правильно понял... но другая логика мне как то на ум не приходит... взять строку из таблици и сделать для нее подзапрос что возвращает до 3х строк, и так далее для каждой категории... на роль подзапроса в голову приходит какраз джоин и табл_сабквери...

-~{}~ 26.11.09 04:56:

мда... лимит в сабквери судя по всему действует на сабквери глобально... т.е. для 3х категорий при лимите три - вернутся не ожидаемые 9 а всего лишь 3... не логично блин... =(
 

dr-sm

Новичок
ты для начала попробуй просто запрос написать который возвращает по три записи для каждой категории из таблицы two,
приджойнить-то всегда успеешь.
мне почему-то кажется, что это не реляционная задача о_О.

-~{}~ 26.11.09 17:28:

hint: тк у нас сверху множество ограничено, то можно запихать результат в один row видимо, через три left join'a c limit 1.
как вот тока с повторениями быть...
 

iamFake

Mind Of Liberty
почитал про ограничения в сабкверях:

Subqueries in the FROM clause cannot be correlated subqueries. They are materialized (executed to produce a result set) before evaluating the outer query, so they cannot be evaluated per row of the outer query.

т.е. как я понял, именно на это ограничение я и напарываюсь, т.к. "they cannot be evaluated per row of the outer query" а мне надо именно чтоб мускул обработав одну строку внешнего запроса для него выполнял подзапрос и так же с каждой следующей строкой внешнего запроса...

на данный момент решил разделить запрос на 2 части, сначала вытаскиваю категории, а потом посредством foreach к каждой категории цепляю до 3х элементов из two таблици...

три джойна с лимитом 1 - это ведь получится что категория и все 3 элемента таблици two будут возвращены одной строкой? это весьма не удобно (иметь идишники элементов two как - id1,id2,id3 вместо id, т.к. эти элементы затем обрабатываются foreach для отображения) и как мне кажется не правильно...
 

Wicked

Новичок
а заранее известно, какие 3 позиции из другой таблицы нужны будут для каждой категории? если да, то можно провести денормализацию: в нужные позиции писать флажок 1 (таких будет макс. 3 для категории), для остальных 0. Тогда можно будет использовать джоин без лимита.
 

iamFake

Mind Of Liberty
к сожалению заранее не известно... 3 позиции из таблици two - это 3 последние добавленные записи...

хм... хотя контроль такого флага впринципе можно возложить на панель администратора, через куда все и добавляется... надо подумать +)

ps интересно, это в мускуле еще не реализовано или "per outer row" табл_сабквери в from не вписывается в концепцию реляционной субд\мускула\скул стандарта?
 

iamFake

Mind Of Liberty
ясно, спасибо за мысль =) с одним запросом жизнь приятней +)
 
Сверху