我正在寻找一个快速的MySQL查询,它返回最低(min
)或最高(max
)价格的产品的ID 价格类别(a, b, c
和d
)。
我有一个名为chocolate_stock
的产品表,其中包含多个价格类别。从特定类别(min
或max
或a
或{{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)
检索此信息的最快方法是什么?
答案 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)) .")
答案 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)).")";
等