Есть ли способ избежать подзапросов с запросом, имеющим три подзапроса

#mysql

#mysql

Вопрос:

У меня есть этот запрос, и он отлично работает (не уверен) в производительности

 SELECT ssp.product_id, p.price
FROM system_step_product AS ssp
JOIN product AS p ON p.product_id=ssp.product_id 
WHERE ssp.system_id = 14
AND ssp.step_number = (
  SELECT step_number
  FROM system_step_product
  WHERE system_id = '14'
  AND step_number > (
    SELECT step_number
    FROM system_step_product
    WHERE system_id = '14'
    AND product_id = '81'
    ORDER BY step_number ASC
    LIMIT 1
  )  
  ORDER BY step_number ASC
  LIMIT 1
)
  

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

Комментарии:

1. Возможно ли использовать join? Который более эффективен, чем внутренние запросы.

Ответ №1:

Два предельных предложения заставляют оператор join требовать row_number() OVER () функции window, которая недоступна в MySQL. И даже это, вероятно, сделало бы ваш запрос менее эффективным, чем он есть в настоящее время.

Ответ №2:

без рассмотрения логики вы можете избавиться от элемента порядка / ограничения 1:

     SELECT ssp.product_id, p.price
    FROM system_step_product AS ssp
    JOIN product AS p ON p.product_id=ssp.product_id 
    WHERE ssp.system_id = 14
    AND ssp.step_number = (
        SELECT MIN(step_number)
        FROM system_step_product
        WHERE system_id = '14'
        AND step_number > (
            SELECT MIN(step_number)
            FROM system_step_product
            WHERE system_id = '14'
            AND product_id = '81'
        )
    )
  

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

plus… определите «лучше» 🙂

Ответ №3:

Это непроверено, но, возможно, вы можете использовать его для сборки.

 select 
        ssp.product_id, 
        p.price 
    from 
        system_step_product as ssp 
    join 
        product as p 
        on p.product_id = ssp.product_id        
    left join
        ( select min(step_number) as min_step_number
          from system_step_product
          where system_id = '14'
            and product_id = '81'
        ) minstep
        on minstep.min_step_number = ssp.step_number
    where
        minstep.min_step_number is null and
        ssp.system_id = 14