как ограничить результаты левого соединения

<p>возьмите случай с двумя таблицами: <code>tbl\_product</code> и <code>tbl\_transaction</code>.<br> <code>tbl\_product</code> перечисляет детали продукта, включая имена и идентификаторы, в то время как <code>tbl\_transaction</code> перечисляет транзакции, связанные с продуктами, и включает даты, идентификаторы продуктов, клиентов и т. д. </p><p>мне нужно отобразить веб-страницу, показывающую 10 продуктов и для каждого продукта последние 5 транзакций. до сих пор ни один запрос <code>left join</code>, похоже, не работал, и подзапрос работал бы, если бы mysql мог разрешить часть <code>tx.product\_id=ta.product\_id</code> (завершается неудачно с<strong> неизвестный столбец «ta.product\_id» в «предложении where»: [ошибка: 1054] </strong>).</p><pre><code>select ta.product\_id, ta.product\_name, tb.transaction\_date from tbl\_product ta left join (select tx.transaction\_date from tbl\_transaction tx where tx.product\_id=ta.product\_id limit 5) tb limit 10 </code></pre><p>есть ли способ получить список, который мне нужен<strong> без использования нескольких запросов в цикле </strong>?</p><p>правка:<br> это именно то, что мне нужно от mysql: </p><pre><code>select ta.product\_id, ta.product\_name, tb.transaction\_date ... from tbl\_product ta left join tbl\_transaction tb on (tb.product\_id=ta.product\_id limit 5) limit 10 </code></pre><p>конечно, это незаконно, но мне бы очень хотелось, чтобы этого не было!</p>

<p>здесь функции ранжирования были бы очень полезны. к сожалению, mysql пока не поддерживает их. вместо этого вы можете попробовать что-то вроде следующего. </p><pre><code>select ta.product\_id, ta.product\_name , tb.transaction\_date from tbl\_product as ta left join ( select tx1.product\_id, tx1.transaction\_id, tx1.transaction\_date , (select count(*) from tbl\_transaction as tx2 where tx2.product\_id = tx1.product\_id and tx2.transaction\_id < tx1.transaction\_id) as [rank] from tbl\_transaction as tx1 ) as tb on tb.product\_id = ta.product\_id and tb.[rank] <= 4 limit 10 </code></pre>

<p>это дает сбой, потому что, когда вы ставите круглые скобки вокруг своего запроса и присваиваете ему псевдоним "tb", вы создали производную таблицу .. ваша производная таблица не знает о таблице tbl\_product, имеющей псевдоним "ta"</p><p>попробуйте использовать on или where за пределами производной таблицы, а затем ссылаться на эту таблицу, используя предоставленный вами псевдоним "tb".</p><p>правка:</p><p>использование «limit» ограничивает результаты запроса во всей его полноте . если у вас есть «limit 10», то на самом деле вам нужно 50 строк (или меньше, если существует менее 5 исторических), верно?</p><p>10 продуктов, соединенных с 5 историческими записями, возвращающими 50 строк.</p><p>в этом случае вы можете иметь решение для одного запроса, соединяющее таблицу продукта с самим собой в производной таблице, имеющей «limit 10»</p><p>такие как:</p><pre><code>select * from tbl\_product ta join (select * from tbl\_product tz where tz.product\_id = ta.product\_id limit 10) tc left join (select tx.transaction\_date from tbl\_transaction tx where tx.product\_id=ta.product\_id limit 5) tb </code></pre><p>вы также можете использовать "in" и указать топ-10, такие как:</p><pre><code>select * from tbl\_product ta left join (select tx.transaction\_date from tbl\_transaction tx where tx.product\_id=ta.product\_id limit 5) tb where ta.product\_id in (select z.product\_id from tbl\_product z limit 10) </code></pre>

<p>правка:</p><p>если вы хотите установить ограничение для каждого продукта, я бы разделил его на два запроса.</p><p>сначала получите список из 10 продуктов, а затем выполните другой запрос для каждого из тех, кто возвращает последние пять транзакций.</p>

<p>я нашел способ сделать left join с подзапросом, отсортированным и ограниченным, он работает на rds amazon, mariadb v10.2 </p><pre><code>left join activities last\_activity on last\_activity.id = ( select id from activities where contester\_id = contesters.id and `type` in ({$last\_activity\_types}) order by id desc limit 1 ) </code></pre><p>все другие способы заставить следующее соединиться с группами и сортировкой не работали для меня. этот пример является рабочим исключением. </p>