Как повернуть таблицу на 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
?
Ответы
Ответ 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