TSQL将表的一列转置为一行

时间:2019-01-15 16:13:48

标签: c# tsql

我有一个临时表,其中一列包含3个数据:CodeDateQuantity

示例:

-------
FR123456
24/02/1988
500

我需要将此列中的数据提取到单独的列中。

示例:

Code     | Date       | Quantity
---------  -----------  ---- 
FR123456 | 24/02/1988 | 500

我使用了以下代码:

SELECT [1], [2], [3]
FROM  
(
    SELECT row_number() OVER (ORDER BY splitdata DESC) AS Id, splitdata  
    FROM splitdata 
) AS SourceTable  
PIVOT  
(  
    MIN (splitdata)
    FOR id IN ([1], [2], [3])  
) AS PivotTable;

它的问题在于,一旦更改了数据内容,由于聚合函数(MIN),我可能会将数量内容放入date列中。

1 个答案:

答案 0 :(得分:1)

我认为这与SQL Server相关...

您的问题是:SQL-Server表没有任何类型的隐式排序顺序。一个简单的SELECT * FROM SomeWhere可以按插入数据的排序顺序返回,但也可以返回完全不同的顺序。确保排序顺序的唯一机会是在最外层查询(针对一组唯一列)上的ORDER BY

您可以通过分析数据来创建排序顺序:

这是带有测试数据的样机表

DECLARE @mockup TABLE(YourColumn VARCHAR(100));
INSERT INTO @mockup VALUES
  ('FR123456')
 ,('24/02/1988')
 ,('500');

-查询将检查值是否可以转换为数字,日期或不转换。
-这将用于对值进行排序。
-我在105中使用CONVERT来强制日期格式 dd-MM-yyyy

 SELECT CASE WHEN TRY_CONVERT(DATE,YourColumn,105) IS NOT NULL THEN 2
             ELSE CASE WHEN TRY_CAST(YourColumn AS INT) IS NOT NULL THEN 3 ELSE 1 
                  END 
        END AS SortOrder
        ,YourColumn
 FROM @mockup
 ORDER BY SortOrder;

但是如果表中有多个三胞胎,而不仅仅是样品中的三胞胎,恐怕您会迷路...

顺便说一句:您自己的方法尝试做的完全一样:

SELECT row_number() OVER (order by splitdata desc)as Id

这会创建一种排序订单号,但它是随机的(根据字母数字规则,数量会出现在日期之前或之后)。

提示

IDENTITY列添加到表中。创建该行时,它将对任何行使用递增的数字。这些值可用于强制插入的命令 (通过在此列中使用ORDER BY)。

更新:您的查询

 SELECT [1], [2] , [3]
    FROM  
    (SELECT CASE WHEN TRY_CONVERT(DATE,splitdata,105) IS NOT NULL THEN 2
             ELSE CASE WHEN TRY_CAST(splitdata AS INT) IS NOT NULL THEN 3 ELSE 1 
                  END 
        END AS Id , splitdata  
    from @mockup ) AS SourceTable  
    PIVOT  
    (  
    MIN (splitdata)
    FOR id IN ([1], [2], [3])  
    ) AS PivotTable;