![](/img/trans.png)
[英]How to get least/min value from multiple columns but ignore 0 as min/least value using mysql?
[英]What is the simplest way to get the least value and second least value from multiple columns (MIN function does not work this)?
下表来自 Teradata 数据库
SELECT
sku.Item_id,
sku.Item_length,
sku.Item_width,
sku.Item_heigth,
FROM Category_item sku
Item_id | Item_length | Item_width |Item_heigth
-------------------------------------------
104174 8 6 1
9482763 8 8 8
8434610 8 9 1
2109145 54 34 2
567106 41 41 2
2028731 3 4 3
我想要的最终结果是,
Item_id | Item_length | Item_width |Item_heigth | MinValue | SecondMinVale
---------------------------------------------------------------------------
104174 8 6 1 1 6
9482763 8 8 8 8 8
8434610 8 9 1 1 8
2109145 54 34 2 2 34
567106 41 41 2 2 41
2028731 3 4 3 3 3
所以我在网上做了一些研究,他们中的大多数使用 MIN 函数和子查询或按分区原始。 Min 函数对我不起作用,因为我有三个单独的列。 我想从上述三列中获得最小或至少两个值。
我尝试使用 Least 函数执行子查询或 CTE,但我坚持获得第二个最小值。 我不确定如何为此使用原始分区。
对此的任何帮助将不胜感激。
非常感谢!!
你可以这样做:
下面这个:
SELECT MIN(Item_caract)
FROM (VALUES (Item_length),(Item_width),(Item_heigth)) a(Item_caract)
给你所有列中的最小值
和这个:
(SELECT MIN(Item_caract)
FROM (VALUES (Item_length),(Item_width),(Item_heigth)) a(Item_caract) where Item_caract >=
(SELECT MIN(Item_caract)
FROM (VALUES (Item_length),(Item_width),(Item_heigth)) a(Item_caract))
给你比上面的最小值大的最小值
以下是完整查询:
select * ,
(SELECT MIN(Item_caract)
FROM (VALUES (Item_length),(Item_width),(Item_heigth)) a(Item_caract))
AS MinValue ,
(SELECT MIN(Item_caract)
FROM (VALUES (Item_length),(Item_width),(Item_heigth)) a(Item_caract) where Item_caract >=
(SELECT MIN(Item_caract)
FROM (VALUES (Item_length),(Item_width),(Item_heigth)) a(Item_caract))
)
AS SecondMinVale
from cte
输出:
104174 8 6 1 1 1
567106 41 41 2 2 2
2028731 3 4 3 3 3
2109145 54 34 2 2 2
8434610 8 9 1 1 1
9482763 8 8 8 8 8
如果没有基于集合的分析函数,您的需求就很困难。 我可能会建议取消数据透视:
WITH cte AS (
SELECT Item_id, Item_length AS item FROM Category_item UNION ALL
SELECT Item_id, Item_width FROM Category_item UNION ALL
SELECT Item_id, Item_height FROM Category_item
),
cte2 AS (
SELECT Item_id, item,
ROW_NUMBER() OVER (PARTITION BY Item_id ORDER BY item) rn
FROM cte
)
SELECT
t1.Item_id,
t1.Item_length,
t1.Item_width,
t1.Item_height,
MAX(CASE WHEN rn = 1 THEN t2.item END) AS MinValue,
MAX(CASE WHEN rn = 2 THEN t2.item END) AS SecondMinValue
FROM Category_item t1
INNER JOIN cte2 t2
ON t1.Item_id = t2.Item_id
WHERE
t2.rn <= 2
GROUP BY
t1.Item_id,
t1.Item_length,
t1.Item_width,
t1.Item_height;
请注意,需要使用这种unpivoting操作可能会严重意味着你的表应与各种测量存储每个项目跨行,而不是跨列进行重新设计。
如果你真的有三列,你可以简单地应用这个蛮力逻辑:
SELECT sku.*,
Least(Item_length,Item_width,Item_height) AS MinValue,
CASE
WHEN Item_length BETWEEN Least(Item_width, Item_height) AND
Greatest(Item_width, Item_height)
THEN Item_length
WHEN Item_width BETWEEN Least(Item_length, Item_height) AND
Greatest(Item_length, Item_height)
THEN Item_width
WHEN Item_height BETWEEN Least(Item_width, Item_length) AND
Greatest(Item_width, Item_length)
THEN Item_height
END AS SecondMinValue
FROM Category_item sku
对于三个以上的列,您需要 Tim 的方法,这是一个轻微的变化(如果您的 TD 版本支持 UNPIVOT)避免连接:
WITH cte AS
(
SELECT up.*
,Row_Number() Over (PARTITION BY item_id ORDER BY val) AS rn
FROM Category_item
UNPIVOT
( val
FOR measure
IN (Item_length AS 'l'
,Item_width AS 'w'
,Item_height AS 'h')
) AS up
)
SELECT
Item_id,
Max(CASE WHEN measure = 'l' THEN val END) AS item_length,
Max(CASE WHEN measure = 'w' THEN val END) AS item_width,
Max(CASE WHEN measure = 'h' THEN val END) AS item_height,
Max(CASE WHEN rn = 1 THEN val END) AS MINVALUE,
Max(CASE WHEN rn = 2 THEN val END) AS SecondMinValue
FROM cte
GROUP BY
Item_id
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.