Сортировка значений в пределах 3 столбцов таблицы в SQL Server - PullRequest
0 голосов
/ 29 мая 2018

В SQL Server 2008 у меня есть таблица, которая содержит 4 столбца:

Item_Code, Length, Width, Height

Мне нужно преобразовать эту таблицу в формат, где длина является максимальным измерением трех, ширина является вторыми высота - третья.

Например:

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

Должен преобразоваться в

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

Может кто-нибудь помочь мне с этим?Возможно ли это в SQL Server 2008?

Ответы [ 4 ]

0 голосов
/ 29 мая 2018

Я бы использовал 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;
0 голосов
/ 29 мая 2018

Оператор CASE, как @SQLChao, был моим первым выбором.Вот другой способ.

-- 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);
0 голосов
/ 29 мая 2018

Немного другой подход

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
0 голосов
/ 29 мая 2018

Вы можете попробовать использовать 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...