Below table is from Teradata database
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
The final result that I want is,
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
So I did a little research online, most of them used MIN function with a subquery or raw over by partition. Min function does not work for me, because I have three separate columns. I want to get minimum or least two values from the above three columns.
I tried to do subquery or CTE using Least function, but I am stuck with getting the second least value. I am not sure how to use raw over partition for this.
Any help regarding this will be highly appreciated.
Thank you so much!!
You can do it this way:
this below:
SELECT MIN(Item_caract)
FROM (VALUES (Item_length),(Item_width),(Item_heigth)) a(Item_caract)
give you the minimum of all columns
and this:
(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))
gives you the minimum that is bigger than the minimum above
Below is the full query:
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
Output:
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
Without set based analytic functions, your requirement is difficult. I might suggest unpivoting your data:
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;
Note that the need to use such unpivoting operations might seriously imply that your table should be redesigned with the various measurements being stored per item across rows , rather than across columns.
If you actually got three columns you can simply apply this brute-force logic:
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
For more than three columns you need Tim's approach, this is a slight variation (if your TD release supports UNPIVOT) avoiding the join-back:
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.