1

In SQL Server 2008, I have a table that contains 4 columns:

Item_Code, Length, Width, Height

I need to transform this table to a format where the length is the max dimension of the three, width is the second, and height is the third.

For example:

Item_Code | Length | Width | Height
----------+--------+-------+-------
123445    | 42.50  | 52.63 | 82.00

Should transform to

Item_Code | Length | Width | Height
----------+--------+-------+-------
123445    | 82.00  | 52.63 | 42.50

Can someone help me with this? Is this possible in SQL Server 2008?

1
  • Are item codes unique ? Commented May 29, 2018 at 20:09

4 Answers 4

2

I would use cross apply:

select t.item_code, v.*
from t cross apply
     (select max(case when seqnum = 1 then val end) as length,
             max(case when seqnum = 2 then val end) as width,
             max(case when seqnum = 3 then val end) as height
      from (select val, row_number() over (order by val desc) as seqnum
            from (values (t.length), (t.width), (t.height)) v(val)
           ) v
     ) v;
Sign up to request clarification or add additional context in comments.

Comments

0

A CASE statement as @SQLChao put together was my first choice. Here's another way.

-- Sample data
DECLARE @table TABLE(Item_Code int, Length decimal(6,2), Width decimal(6,2), Height decimal(6,2))
INSERT @table VALUES (123445,42.50,52.63,82.00),(123999,20.50,20.50,10.00),(123000,22.50,22.50,90.00),
                     (123444,22.50,90.00,90.00),(123555,90.00,90.00,90.00),(123222,100,90.00,90.00);

-- solution
SELECT 
  Item_Code,
  Length = fx.mx,
  Width  = CASE WHEN t.Width  = fx.mx THEN Length ELSE Width  END,
  Height = CASE WHEN t.Height = fx.mx THEN Length ELSE Height END
  FROM @table t
CROSS APPLY 
(
  SELECT MAX(x), MIN(x)
    FROM (VALUES (t.Length),(t.Width), (t.Height)) f(x)
) fx(mx,mn);

Comments

0

A little different approach

DECLARE @table TABLE(Item_Code int, Length decimal(6,2), Width decimal(6,2), Height decimal(6,2))
INSERT @table VALUES (123445,42.50,52.63,82.00),(123999,20.50,20.50,10.00),(123000,22.50,22.50,90.00),
                     (123444,22.50,90.00,90.00),(123555,90.00,90.00,90.00),(123222,100,90.00,90.00); 
--select * from @table;

with cte1 as 
(
    select Item_Code, Length as dimension from @table
    union all 
    select Item_Code, Width from @table
    union all 
    select Item_Code, Height from @table
)
, cte2 as 
(
   select * 
        , ROW_NUMBER() over (partition by Item_Code order by dimension desc) as rn
   from cte1
)
select l.Item_Code, l.dimension as Length, w.dimension as Width, h.dimension as height 
from cte2 as l 
join cte2 as w
  on w.Item_Code = l.Item_Code 
 and l.rn = 1 
 and w.rn = 2
join cte2 as h
  on h.Item_Code = l.Item_Code 
 and h.rn = 3 
order by Item_Code

Comments

0

You could try using CASE

SELECT 
  CASE 
    WHEN length >= width AND length >= height THEN length
    WHEN width >= length AND width >= height THEN width
    WHEN height >= length AND height >= width THEN height
  END AS [Length],
  CASE 
    WHEN (length >= width AND length <= height) OR (length <= width AND length >= height)  THEN length
    WHEN (width >= length AND width <= height) OR (width <= length AND width >= height)  THEN width
    WHEN (height >= length AND height <= width) OR (height <= length AND height >= width) THEN height
  END AS [Width],
  CASE 
    WHEN length <= width AND length <= height THEN length
    WHEN width <= length AND width <= height THEN width
    WHEN height <= length AND height <= width THEN height
END AS [Height]
FROM YourTable

3 Comments

This is good but returns a NULL when you have ties on the highest value. May need to add some >= logic
Thanks for the suggestion. I added the =. I believe it should work out because it doesn't matter which value is returned if they are equal.
Better bet still getting NULL for Width when width=Length and those are the two highest values. I updated my answer below to include a few different sample data scenarios to test against.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.