web-dev-qa-db-ja.com

MySQLテーブルから最も近い値を見つける

下の表から特定の値の最も近いレートをフェッチしたい。

mysql> select * from rates;
+------+----------+----------+
| ID   |   Type   |   Rate   |
+------+---------------------+
| 1    |    A     |    12    |
| 2    |    A     |    18    |
| 3    |    A     |    25    |
| 4    |    A     |    27    |
| 5    |    A     |    34    |
| 6    |    A     |    38    |
| 7    |    B     |    40    |
| 8    |    B     |    43    |
| 9    |    B     |    50    |
| 10   |    A     |    55    |
| 11   |    A     |    58    |
| 12   |    A     |    62    |
+------+---------------------+

たとえば、12に最も近いレートを取得するには、12, 18, 25を返す必要があります。同様に、25に最も近いのは18,25,27です。

多くの方法を試しましたが、うまくいきませんでした。

SELECT ID,
       TYPE,
       Rate
FROM (
        (SELECT *
         FROM
           (SELECT *
            FROM rates
            ORDER BY Rate DESC) a
         WHERE a.Type ='A'
           AND a.Rate <=25 LIMIT 0 ,
                                 1)
      UNION
        (SELECT *
         FROM
           (SELECT *
            FROM rates
            ORDER BY Rate ASC) b
         WHERE b.Type ='A'
           AND b.Rate >25 LIMIT 0 ,
                                3)) r
GROUP BY r.Rate
ORDER BY r.Rate ASC LIMIT 3

25, 27, 34が返されますが、実際は18,25,27が返されます。助言がありますか?

2
Tahir Yasin
SELECT id, type, rate
FROM
( ( SELECT id, type, rate, 25-rate AS diff
    FROM rates
    WHERE type = 'A'
      AND rate < 25
    ORDER BY rate DESC
      LIMIT 3
  ) 
  UNION ALL
  ( SELECT id, type, rate, rate-25 AS diff
    FROM rates
    WHERE type = 'A'
      AND rate >= 25
    ORDER BY rate ASC
      LIMIT 3
  ) 
) AS tmp
ORDER BY diff
LIMIT 3 ;

SQL-Fiddleでテストする

2
ypercubeᵀᴹ

もっと簡単にできると思います。

select id, type, rate, abs(25 - rate) as delta
from rates
order by delta
LIMIT 3
1
Frans
        $table = 'category';
        //$where = $table.'.Width'.' < '.$size .' or '.$table.'.Height > '.$size;

        $where = 'CAST(Width AS decimal) >= CAST('.$size.' AS decimal) and CAST(Height AS decimal) <= CAST('.$size.' AS decimal)';

    return $this->db->select($table.'.Width,'.$table.'.Height')
            ->from($table)
            ->where($where)
            ->group_by('Width ,Height')
            ->limit(5)
            ->get()->result_array();

最初にクエリをデータベースに送信し、次にレコードをそのfunに渡します

public function getNearestValue($ records、$ size){$ closest = null; foreach($ records as $ item){

        if ($closest === null ||  abs($size - $closest) > abs($item['Width'] - $size) || abs($size - $closest) > abs($item['Height'] - $size)) {
            $closest = $item['Width'];
        }
    }
    return $closest;
}
0
user155152