Получить строки моего вывода, отсортированные в порядке возрастания из этой таблицы? - PullRequest
0 голосов
/ 19 октября 2019

Я использую SQL Server 2014, и у меня есть следующая таблица (t1), которая содержит около 5000 строк. Вот выдержка из t1:

 n1   n2   n3   n4   n5   n6  Type
 6    15   10   11   22   25   C1
 2     5    1   20   21   30   C1
15    25   18    4   12   38   C2
11     1    4    9   24   31   C2
...

Мне нужно выбрать все строки в таблице, но я хочу, чтобы выходные данные были отсортированы по возрастанию для каждой строки.

Вотожидаемый результат:

 Nr1   Nr2   Nr3  Nr4   Nr5  Nr6   Type
  6    10    11   15    22   25     C1
  1     2     5   20    21   30     C1
  4    12    15   18    25   38     C2
  1     4     9   11    24   31     C2
  ...

Я знаю, как ORDER BY столбцы, но я полностью застрял в том, как решить эту проблему. Нужно ли мне pivot данные, отсортировать их, а затем отключить для достижения этой цели?

Примечание. Я добавил столбец Id в свой столбец. Теперь у каждой строки есть уникальный идентификатор (1,2,3, ...)

Моя попытка в соответствии с решением Менно:

;with cte1 as (

SELECT [id], [type], Col, Val
FROM (  
  SELECT [id], [n1], [n2], [n3], [n4], [n5], [n6], [type]
  FROM [t1] ) t
UNPIVOT
   (Col FOR Val IN ([n1], [n2], [n3], [n4], [n5], [n6]))
AS tblUnPivot

),

cte2 as (

Select

ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Val) OrderedVals, * 

from [cte1]

),

cte3 as (

SELECT [id], [type], Col, Val
FROM (  
  SELECT [OrderedVals], [id], [type], [Col]
  FROM [cte2] ) s
PIVOT
   (??? FOR OrderedVals IN ([1],[2],[3],[4],[5],[6]))

AS tblPivot

)

select * from [cte3]

Ответы [ 4 ]

4 голосов
/ 19 октября 2019

Предполагая , что существует какой-то столбец идентификатора, вы можете отменить поворот значений, а затем Повернуть их обратно, используя VALUES и кросс-таблицу:

CREATE TABLE dbo.YourTable (ID int IDENTITY, --Required to work
                            n1 tinyint,
                            n2 tinyint,
                            n3 tinyint,
                            n4 tinyint,
                            n5 tinyint,
                            n6 tinyint,
                            [Type] char(2));
GO

INSERT INTO dbo.YourTable (n1,n2, n3, n4, n5, n6, [Type])
VALUES( 6,15,10,11,22,25,'C1'),
      ( 2, 5, 1,20,21,30,'C1'),
      (15,25,18, 4,12,38,'C2'),
      (11, 1, 4, 9,24,31,'C2');

GO

SELECT *
FROM dbo.YourTable;

WITH unPvt AS (
    SELECT YT.ID,
           YT.[Type],
           V.Val,
           ROW_NUMBER() OVER (PARTITION BY YT.ID ORDER BY V.Val) AS NewPos
    FROM dbo.YourTable YT
         CROSS APPLY (VALUES(1,YT.n1),
                            (2,YT.n2),
                            (3,YT.n3),
                            (4,YT.n4),
                            (5,YT.n5),
                            (6,YT.n6))V(Pos,Val))
SELECT MAX(CASE NewPos WHEN 1 THEN Val END) AS n1,
       MAX(CASE NewPos WHEN 2 THEN Val END) AS n2,
       MAX(CASE NewPos WHEN 3 THEN Val END) AS n3,
       MAX(CASE NewPos WHEN 4 THEN Val END) AS n4,
       MAX(CASE NewPos WHEN 5 THEN Val END) AS n5,
       MAX(CASE NewPos WHEN 6 THEN Val END) AS n6,
       [Type]
FROM unPvt
GROUP BY ID,[Type]
ORDER BY [Type];


GO
DROP TABLE dbo.YourTable;
1 голос
/ 19 октября 2019

Это похоже на ответ Ларну, но оно должно иметь лучшую производительность , поскольку оно позволяет избежать агрегирования по всей таблице . Кроме того, он возвращает те же строки, что и в исходных данных, без введения подделки id.

. Вы можете агрегировать в пределах CROSS APPLY:

SELECT v.*, t.type
FROM t CROSS APPLY
     (SELECT MAX(CASE WHEN seqnum = 1 THEN n END) as n1,
             MAX(CASE WHEN seqnum = 2 THEN n END) as n2,
             MAX(CASE WHEN seqnum = 3 THEN n END) as n3,
             MAX(CASE WHEN seqnum = 4 THEN n END) as n4,
             MAX(CASE WHEN seqnum = 5 THEN n END) as n5,
             MAX(CASE WHEN seqnum = 6 THEN n END) as n6
      FROM (SELECT v.n,
                   ROW_NUMBER() OVER (ORDER BY n) as seqnum
            FROM (VALUES (t.n1), (t.n2), (t.n3), (t.n4), (t.n5), (t.n6)
                 ) v(n)
           ) v
     ) v;
1 голос
/ 19 октября 2019
  • Вы можете присвоить каждой строке уникальный идентификатор, например: ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) ID
  • Затем вы можете отменить вывод данных, например: Col FOR Val IN ([Nr1], [Nr2], [Nr3], [Nr4], [Nr5], [Nr 6])
  • Затем упорядочить значениедля каждого идентификатора, например: ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Val) OrderedVals
  • Затем измените ваши данные FOR OrderedVals IN ([1],[2],[3],[4],[5],[6])
0 голосов
/ 19 октября 2019

Вы можете использовать этот код без использования pivot

DECLARE @T 
TABLE(n1 INT, n2 INT, n3 INT, n4 INT, n5 INT, n6 INT,Type VARCHAR(10))

INSERT INTO @T(n1,   n2,   n3,   n4,   n5,   n6,  Type)
      SELECT  6  ,  15  , 10  , 11 , 22  , 25  , 'C1'
UNION SELECT  2  ,  5   , 1   , 20 , 21  , 30  , 'C1'
UNION SELECT  15 ,  25  , 18  , 4  , 12  , 38  , 'C2'
UNION SELECT  11 ,  1   , 4   , 9  , 24  , 31  , 'C2'

SELECT SUM(CASE WHEN ord=1 THEN n ELSE 0 END) AS Nr1,
       SUM(CASE WHEN ord=2 THEN n ELSE 0 END) AS Nr2,
       SUM(CASE WHEN ord=3 THEN n ELSE 0 END) AS Nr3,
       SUM(CASE WHEN ord=4 THEN n ELSE 0 END) AS Nr4,
       SUM(CASE WHEN ord=5 THEN n ELSE 0 END) AS Nr5,
       SUM(CASE WHEN ord=6 THEN n ELSE 0 END) AS Nr6,
       Type
FROM (SELECT *,ROW_NUMBER()OVER(ORDER by Type) as unq
      FROM @T
)AS IndexedT
CROSS APPLY(SELECT n , ROW_NUMBER()OVER(ORDER by n) as ord
            FROM (      SELECT n1 as n 
                  UNION SELECT n2       
                  UNION SELECT n3      
                  UNION SELECT n4       
                  UNION SELECT n5       
                  UNION SELECT n6      
            )as X
) AS PivotItem
GROUP BY unq,Type
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...