2011-02-26 32 views
39

我有一張桌子。如何將表格旋轉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中這樣做?

+0

@Richard 我使用的是SQL Server 2005或2008 – 2011-02-27 16:08:10

+2

我能知道什麼是旋轉的目的表值爲45度? – RGS 2016-05-11 10:34:34

回答

64

工作的完整示例(用於SQL Server 2005+)
如果你需要它的另一個系統,也有等效對於拼圖的碎片下面

  • ROW_NUMBER()
  • DENSE_RANK()
  • UN /樞

您可以找到其他的問題#1等同。例如,前兩項得到了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來生成上面顯示的模式。

+5

感謝理查德,你真是一位SQL大師! – 2011-02-27 16:09:14

+13

這是我見過的最聰明的事情之一。即使純粹的理論價值,我想在博客中看到這個解釋和推廣45度的倍數。傑出的理查德。對不起,如果我聽起來像一個粉絲男孩,但我真的很驚訝這個:) – 2011-02-27 21:09:47

+2

要獲得ypercube的輸出,改變'targetCol = ROW_NUMBER()..'到'targetCol = ABS(3 - (row + col-1)) -1 + 2 * ROW_NUMBER()..'如果靈感有助於擴大答案,我會添加更多評論 – RichardTheKiwi 2011-03-02 19:18:21

3

有直接在SQL這樣做沒有簡單的方法。

我建議你結果導入到一個不同的編程環境,如Java,PHP,Python或什麼都,解決這方面的問題,然後(如有必要)把結果返回到數據庫。

8

不該表

--------- 
| 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 | | | 
--------------------- 
+4

這不是一個答案。 – aioobe 2011-02-26 12:32:23

+23

不,但我無法將這些表格粘貼到評論中。在嘗試回答之前,我們應該清楚地描述問題,不是嗎? – 2011-02-26 13:09:41

+5

ypercube - 多走一步(衝到左邊),你就會有問題結構 – RichardTheKiwi 2011-02-26 21:16:27

0

選項爲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

相關問題