You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SQL Server将Excel导入的日期数字转回日期格式及行转列需求

搞定Excel日期数字转SQL Server日期+UNPIVOT的方案

我明白你现在的困境:从Excel导数据时,日期列标题被SQL Server转成了像42845这样的数字,改Excel格式再导也没用,现在要通过视图用UNPIVOT把这些日期列转成行,同时得把数字转回正常日期。别担心,这事儿不难解决!

首先得搞懂:Excel里的日期数字本质是从1900年1月0日开始算的累计天数(不过Excel有个1900年是闰年的bug,所以实际要从1899-12-30开始计算,才能和SQL Server的日期对齐)。所以我们用DATEADD函数就能轻松转回来。

第一步:先搞定单个数字转日期

直接用这个公式就能把数字转成标准日期:

SELECT DATEADD(day, 42845, '1899-12-30') AS ConvertedDate;
-- 算出来就是2017-06-01,对应Excel里的2017/6/1

第二步:结合UNPIVOT创建视图

假设你导入后的表叫ImportedData,结构大概是这样的:

IDProduct428454284642847
1产品A100150200
2产品B8090110

要把这些数字日期列转成行,同时转成日期格式,创建视图的SQL可以这么写:

CREATE VIEW vw_UnpivotedData
AS
SELECT 
    ID,
    Product,
    -- 把数字列名转成日期
    DATEADD(day, CAST(DateNumber AS INT), '1899-12-30') AS TransactionDate,
    Value
FROM 
    ImportedData
UNPIVOT (
    Value FOR DateNumber IN ([42845], [42846], [42847])
) AS UnpivotResult;

第三步:如果日期列很多,用动态SQL自动处理

要是每次导入的日期列数量都不一样,硬写列名太麻烦,那就用动态SQL来自动生成UNPIVOT语句:

DECLARE @cols NVARCHAR(MAX), @query NVARCHAR(MAX);

-- 自动获取所有数字格式的日期列名
SELECT @cols = STRING_AGG(QUOTENAME(name), ', ')
FROM sys.columns
WHERE object_id = OBJECT_ID('ImportedData')
  AND ISNUMERIC(name) = 1; -- 只挑数字列名

-- 构建动态创建视图的SQL
SET @query = N'
CREATE VIEW vw_DynamicUnpivotedData
AS
SELECT 
    ID,
    Product,
    DATEADD(day, CAST(DateNumber AS INT), ''1899-12-30'') AS TransactionDate,
    Value
FROM 
    ImportedData
UNPIVOT (
    Value FOR DateNumber IN (' + @cols + N')
) AS UnpivotResult;';

-- 执行语句创建视图
EXEC sp_executesql @query;

小提醒

  • 要确保那些数字列名确实是Excel转过来的日期数字,如果有其他数字列,得调整筛选条件。
  • 要是你用的是苹果系统的Excel(默认1904日期系统),那起始日期要改成1904-01-01,公式变成DATEADD(day, [日期数字], '1904-01-01'),不过大部分Windows环境的Excel都是1900系统,不用改。

内容的提问来源于stack exchange,提问作者Otshepeng Ditshego

火山引擎 最新活动