SELECT id其中多列的最小值或最大值

时间:2013-05-28 12:58:28

标签: php mysql sql pdo

我正在寻找一个快速的MySQL查询,它返回最低(min)或最高(max)价格的产品的ID 价格类别(a, b, cd)。

我有一个名为chocolate_stock的产品表,其中包含多个价格类别。从特定类别(minmaxa或{{1获得最低价格(b)或最高价格c)非常容易}})。

d

价格类别为id | name | price_a | price_b | price_c | price_d | -------------------------------------------------------------- 1 | Chips Ahoy | 250 | 530 | 720 | 120 -------------------------------------------------------------- 2 | Chocolate Chunk | 250 | 90 | 32.92 | 110 -------------------------------------------------------------- 3 | Oreo | 103 | 44.52 | 250 | 850 -------------------------------------------------------------- 。以下是从类别中返回最高价格的示例,不是ID:

decimal(10,2)

检索此信息的最快方法是什么?

5 个答案:

答案 0 :(得分:1)

如果您要将输出的内容列表,可能会有所帮助,但我认为您缺少的部分是HAVING子句。

首先 - 试试这个

select min(id), max(price_a) from $t having price_a = max(price_a)

然后尝试

select min(id), min(price_a) from $t having price_a = min(price_a)
union
select min(id), max(price_a) from $t having price_a = max(price_a)

答案 1 :(得分:1)

此查询可以执行您想要的操作:

(select t.*
 from $t t
 where . . .
 order by price_a desc
 limit 1) union all
 (select t.*
 from $t t
 where . . .
 order by price_b desc
 limit 1) union all
(select t.*
 from $t t
 where . . .
 order by price_c desc
 limit 1) union all
(select t.*
 from $t t
 where . . .
 order by price_d desc
 limit 1)

如果您在id上有索引,那么它的表现应该相当不错。

这种方法需要四次遍历表(尽管id上的索引应该大大减少)。以下方法只需要一次通过表格:

select MAX(price_a),
       substring_index(group_concat(id order by price_a desc), ',', 1),
       max(price_b),
       substring_index(group_concat(id order by price_b desc), ',', 1),
       max(price_c),
       substring_index(group_concat(id order by price_c desc), ',', 1),
       max(price_d),
       substring_index(group_concat(id order by price_d desc), ',', 1)
from $t
where . . .

它使用group_concat()substring_index()的技巧来获取每列的最大ID。

答案 2 :(得分:1)

您要做的第一件事是规范化您的数据,以便以后查询我会创建以下视图:

CREATE VIEW NormalT
AS
    SELECT  ID, Name, 'Price_a' AS Type, Price_a AS Price
    FROM    T
    UNION ALL
    SELECT  ID, Name, 'Price_b' AS Type, Price_b AS Price
    FROM    T
    UNION ALL
    SELECT  ID, Name, 'Price_c' AS Type, Price_c AS Price
    FROM    T
    UNION ALL
    SELECT  ID, Name, 'Price_d' AS Type, Price_d AS Price
    FROM    T;

然后我不确定你想要的格式,如果你想要每个价格的最小值,你可以使用它:

SELECT  mt.Type2,
        mt.Type,
        mt.Price,
        t.ID,
        t.Name
FROM    (   SELECT  Type, MIN(Price) AS Price, 'MIN' AS Type2
            FROM    NormalT
            GROUP BY Type
            UNION ALL
            SELECT  Type, MAX(Price) AS Price, 'MAX' AS Type2
            FROM    NormalT
            GROUP BY Type
        ) mt
        INNER JOIN NormalT T
            ON mt.Type = T.Type
            AND mt.Price = t.Price
ORDER BY mt.Type2, mt.Type, t.ID;

将从您的示例数据中输出以下内容:

TYPE2   TYPE        PRICE   ID  NAME
MAX     Price_a     250     1   Chips Ahoy
MAX     Price_a     250     2   Chocolate Chunk
MAX     Price_b     530     1   Chips Ahoy
MAX     Price_c     720     1   Chips Ahoy
MAX     Price_d     850     3   Oreo
MIN     Price_a     103     3   Oreo
MIN     Price_b     44.52   3   Oreo
MIN     Price_c     32.92   2   Chocolate Chunk
MIN     Price_d     110     2   Chocolate Chunk

但是,如果它只是所有价格(a,b,c和d)的最小值和最大值,那么你可以使用它:

SELECT  mt.Type2,
        t.Type,
        mt.Price,
        t.ID,
        t.Name
FROM    (   SELECT  MIN(Price) AS Price, 'MIN' AS Type2
            FROM    NormalT
            UNION ALL
            SELECT  MAX(Price) AS Price, 'MAX' AS Type2
            FROM    NormalT
        ) mt
        INNER JOIN NormalT T
            ON mt.Price = t.Price;

哪个会输出:

TYPE2   TYPE    PRICE       ID  NAME
MIN     Price_c     32.92   2   Chocolate Chunk
MAX     Price_d     850     3   Oreo

<强> Examples on SQL Fiddle

答案 3 :(得分:1)

试试这个,它正在模拟Analytics,因为默认情况下MYSQL没有它们:

SELECT id, 
             ( select MAX(price_a) from $t t2 where  t2.id = t1.id ) AS price_a, 
             ( select MAX(price_b) from $t t2 where  t2.id = t1.id ) AS price_b, 
             ( select MAX(price_c) from $t t2 where  t2.id = t1.id ) AS price_c, 
             ( select MAX(price_d) from $t t2 where  t2.id = t1.id ) AS price_d 
             FROM $t t1 WHERE id IN(". implode(',', array_map('intval', $arrIds)) .")

来自:http://www.oreillynet.com/pub/a/mysql/2007/03/29/emulating-analytic-aka-ranking-functions-with-mysql.html?page=3

答案 4 :(得分:-1)

你没有得到id,因为MAX返回一个值。但是id不是这样。你可以使用像

这样的单独查询
SELECT id,MAX(price_a) FROM $t WHERE id IN (". implode(',', array_map('intval', $arrIds)).")";
SELECT id,MAX(price_b) FROM $t WHERE id IN (". implode(',', array_map('intval', $arrIds)).")";