Подтвердить что ты не робот

Как повернуть таблицу на 45 градусов и сохранить результат в другой таблице?

У меня есть таблица.

---------
| a | b |
---------
| a | b |
---------

Я хочу повернуть его на 45 градусов (по часовой стрелке или против часовой стрелки) и сохранить его в другую таблицу. Например, если я поверну его на 45 градусов против часовой стрелки, это будет:

-------------
| b |   |   |
-------------
| a | b |   |
-------------
| a |   |   |
-------------

Другой пример, когда я вращаю

-------------
| a | b | c |
-------------
| d | e | f |
-------------
| g | h | i |
-------------

Он изменится на

---------------------
| c |   |   |   |   |
---------------------
| b | f |   |   |   |
---------------------
| a | e | i |   |   |
---------------------
| d | h |   |   |   |
---------------------
| g |   |   |   |   |
---------------------

Как это сделать в SQL?

4b9b3361

Ответ 1

Полностью рабочий пример (для SQL Server 2005+)
Если вам это нужно для другой системы, есть эквиваленты для частей головоломки ниже

  • row_number()
  • DENSE_RANK()
  • ип/поворота

Вы можете найти эквиваленты из других вопросов Stackoverflow. Например, первые два хорошо поддерживаются Oracle и DB2.

create table t45 (id int identity, colA char(1), colX char(1), colZ char(1))
insert t45 select 'a','b','c'
insert t45 select 'd','e','f'
insert t45 select 'g','h','i'
GO

select [1],[2],[3],[4],[5] -- for N columns, this goes to N*2-1
from
(
    select value,
        targetRow = row+col-1,
        targetCol = ROW_NUMBER() over (partition by row+col-1 order by row)
    from
    (
        select *,
            row = DENSE_RANK() over (order by id),
            col = ROW_NUMBER() over (partition by id order by
                CASE source when 'colA' then 3 -- number in reverse
                            when 'colX' then 2
                            when 'colZ' then 1 end)
        from t45
        unpivot (value for source in (colA,colX,colZ)) upv
    ) x
) p                                -- for N columns, this goes to N*2-1
pivot (max(value) for targetCol in ([1],[2],[3],[4],[5])) pv
order by targetRow

Если вам нужно произвольно применить его к любой таблице - используйте динамический SQL для создания шаблона, показанного выше.

Ответ 2

Не следует использовать таблицу

---------
| a | b |
---------
| a | b |
---------

повернуто на 45 градусов против часовой стрелки, как это?

-------------
|   | b |   |
-------------
| a |   | b |
-------------
|   | a |   |
-------------

и

-------------
| a | b | c |
-------------
| d | e | f |
-------------
| g | h | i |
-------------

что-то вроде:

---------------------
|   |   | c |   |   |
---------------------
|   | b |   | f |   |
---------------------
| a |   | e |   | i |
---------------------
|   | d |   | h |   |
---------------------
|   |   | g |   |   |
---------------------

Ответ 3

Нет простого способа сделать это непосредственно в SQL.

Я предлагаю вам импортировать результат в другую среду программирования, такую ​​как Java, PHP, Python или что бы то ни было, решить проблему в этом контексте, а затем (при необходимости) вернуть результат в базу данных.

Ответ 4

Опция для SQLServer2008 + с операторами CROSS APPLY и PIVOT

CREATE TABLE dbo.test77
 (
  id int IDENTITY, 
  colA char(1), 
  colB char(1), 
  colC char(1)
  )

INSERT dbo.test77
VALUES('a','b','c'),
      ('d','e','f'),
      ('g','h','i')

SELECT [1], [2], [3], [4], [5]
FROM (
      SELECT COALESCE(o.colA, o.colB, o.colC) AS Val,
             'Col' + CAST(ROW_NUMBER() OVER (ORDER BY id) AS nvarchar(1)) AS ColName 
      FROM dbo.test77 t CROSS APPLY (
                                     VALUES(colA, NULL, NULL),
                                           (NULL, colB, NULL),
                                           (NULL, NULL, colC)
                                     ) o(colA, colB, colC)
      ) p
PIVOT (
MAX(Val) FOR ColName IN ([Col1], [Col2], [Col3], [Col4], [Col5], [Col6], [Col7], [Col8], [Col9])
) pvt CROSS APPLY (
                   VALUES ([Col3], NULL, NULL, NULL, NULL),
                          ([Col2], [Col6], NULL, NULL, NULL),
                          ([Col1], [Col5], [Col9], NULL, NULL),
                          ([Col4], [Col8], NULL, NULL, NULL),
                          ([Col7], NULL, NULL, NULL, NULL)
                   ) o([1], [2], [3], [4], [5])

Демо на SQLFiddle