SQL - найти ближайшую цену к данному аргументу - PullRequest
0 голосов
/ 12 октября 2011

Я пытаюсь найти кортежи, цена которых ближе всего к данному параметру в SQL.Например: параметр price = 6 вернул бы id 1 и 2. Параметр price = 20 вернул бы id 3.

Таблица:

ID     PRICE
1      5
2      5
3      10

SELECT id 
FROM Table
WHERE table.price ?? 6

Есть идеи как это сделать?

Спасибо.

Ответы [ 4 ]

1 голос
/ 12 октября 2011
SELECT id, price
FROM thetable t1
WHERE NOT EXISTS ( SELECT *
   FROM thetable t2
   WHERE abs (t2.price - 6) < abs (t1.price - 6)
   );
1 голос
/ 12 октября 2011

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

SELECT *
FROM Table
WHERE price = ( --could also use "WHERE price in" here...
    SELECT TOP 1 price FROM Table
    GROUP BY price
    ORDER BY Min(Abs(price - ?)))
1 голос
/ 12 октября 2011
SELECT ID
FROM TableX
WHERE PRICE = @CheckPrice +
      ( SELECT MIN(ABS(PRICE - @CheckPrice))
        FROM TableX
      )
   OR PRICE = @CheckPrice -
      ( SELECT MIN(ABS(PRICE - @CheckPrice))
        FROM TableX
      )

или (вероятно, лучше для производительности):

SELECT ID
FROM 
    TableX
  CROSS JOIN
          ( SELECT 
                ( SELECT MIN(PRICE) - @CheckPrice
                  FROM TableX
                  WHERE PRICE >= @CheckPrice
                ) AS Pover 
              , ( SELECT @CheckPrice - MAX(PRICE)
                  FROM TableX
                  WHERE PRICE <= @CheckPrice
                ) AS Punder
            FROM dual
          ) AS tmp 
WHERE PRICE IN ( @CheckPrice + LEAST(Pover, Punder)
               , @CheckPrice - LEAST(Pover, Punder)
               )
0 голосов
/ 04 декабря 2012

Мы используем подзапрос UNION для получения ближайших цен по целевой цене.В каждом подзапросе мы получаем абсолютную дельту (разницу между ценой каждой модели и целевой ценой) и дельту ORDER BY в конце.Работает довольно быстро и стабильно.Надеюсь, это поможет;)

SET @CheckPrice = 3910;

(
    SELECT
        m_id,
        m_name,
        m_auto_price,
        m_auto_discount,
        ABS(m_auto_price - @CheckPrice)AS delta
    FROM
        s_models
    WHERE
        m_auto_price >= @CheckPrice
    ORDER BY
        m_auto_price ASC
    LIMIT 10
)
UNION
    (
        SELECT
            m_id,
            m_name,
            m_auto_price,
            m_auto_discount,
            ABS(m_auto_price - @CheckPrice)AS delta
        FROM
            s_models
        WHERE
            m_auto_price <= @CheckPrice
        ORDER BY
            m_auto_price DESC
        LIMIT 10
    )
ORDER BY
    delta ASC,
    m_auto_price DESC,
    m_auto_discount DESC
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...