如何将列转换为行以进行sql查询

时间:2018-01-10 19:15:56

标签: sql sql-server pivot

我有以下格式找到的预算信息(excel) company,salesrep,week1,week2,week3和每周的每列代表预算金额。问题是我试图加入一个包含以下列的表 weeknumber,company,salesrep,预算金额。很明显,我不能通过做weeknumber = week1来加入。如何构建连接以允许此操作。我可以浏览整个Excel电子表格中的100k行,并为每行提供一周的数字,并添加一个显示预算金额的列。但这将是相当多的工作。无论如何以编程方式完成此操作?非常感谢您的帮助。正如评论所述,编辑***。我使用了以下查询:

SELECT CompanyKey, Subcategory, ItemKey, CustomerKey, SalesRepKey, Pounds
FROM 
(SELECT CompanyKey, Company, CompanyDesc, Subcategory, SubcategoryDesc, 
ItemKey, ItemDesc, CustomerKey, CustomerDesc, SalesRepKey, SalesRep, Wk_1, 
Wk_2, Wk_3, Wk_4, Wk_5, Wk_6, Wk_7, Wk_8, Wk_9, Wk_10, Wk_11, Wk_12, Wk_13, 
Wk_14,
Wk_15, Wk_16, Wk_17, Wk_18, Wk_19, Wk_20, Wk_21, Wk_22, Wk_23, Wk_24, Wk_25, 
Wk_26, Wk_27, Wk_28, Wk_29, Wk_30, Wk_31, Wk_32, Wk_33, Wk_34, Wk_35, Wk_36, 
Wk_37, Wk_38, Wk_39, Wk_40, Wk_41, Wk_42, Wk_43, Wk_44, Wk_45, Wk_46, Wk_47,
Wk_48, Wk_49, Wk_50, Wk_51, Wk_52, Wk_53 FROM Budget_Master) p
UNPIVOT
(Pounds FOR [week] IN 
  (Wk_1, Wk_2, Wk_3, Wk_4, Wk_5, Wk_6, Wk_7, Wk_8, Wk_9, Wk_10, Wk_11, 
Wk_12, Wk_13, Wk_14,
Wk_15, Wk_16, Wk_17, Wk_18, Wk_19, Wk_20, Wk_21, Wk_22, Wk_23, Wk_24, Wk_25, 
Wk_26, Wk_27, Wk_28, Wk_29, Wk_30, Wk_31, Wk_32, Wk_33, Wk_34, Wk_35, Wk_36, 
Wk_37, Wk_38, Wk_39, Wk_40, Wk_41, Wk_42, Wk_43, Wk_44, Wk_45, Wk_46, Wk_47,
Wk_48, Wk_49, Wk_50, Wk_51, Wk_52, Wk_53)
) AS unpvt

这给了我以下结果:enter image description here

到目前为止这种情况很好,但是我需要添加一个额外的列,说明它是什么周#。我不知道每一行谈论的是几周。它看起来像ASC排序,所以我可以假设所有行都是1-53周,但我不想假设。有没有办法修改此命令以显示周#也?

2 个答案:

答案 0 :(得分:2)

如评论所述,请考虑SQL Server的UNPIVOT。但是,您需要从Excel文件中获取信息,因此如果用户权限允许,请考虑OPENROWSET

SELECT company, salesrep, week, budgetamount
FROM 
   (SELECT company, salesrep, week1, week2, week3, ..., week53
   FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
                   'Excel 12.0; Database=C:\Path\To\Excel\File; HDR=YES; IMEX=1', [SheetName$]) e) p
UNPIVOT
   (budgetamount FOR week IN 
      (week1, week2, week3, ..., week53)
) AS unpvt;

Rextester Demo

答案 1 :(得分:1)

虽然您可以使用UNPIVOT,但我发现交叉应用更容易编写和理解。 (另外,如果您有多个要拆分的列,则扩展代码会更容易

CREATE table #Budget
(COMPANY INTEGER NOT NULL,
 REP CHAR(10) NOT  NULL,
 WK1 NUMERIC(9,2) NULL,
 wk2 NUMERIC(9,2) NULL,
 wk3 NUMERIC(9,2) NULL,
wk4 NUMERIC(9,2) NULL,
 CONSTRAINT pk_#budget PRIMARY kEY CLUSTERED (Company, REP)
 )
 INSERT INTO #Budget
 (
     COMPANY,
     REP,
     WK1,
     WK2,
     WK3,
     WK4
 )
 VALUES
 (   1, 'ADAM',20,30,40,50),
 (   1, 'JOE',40,50,75,80)

 SELECT bud.COMPANY,
        bud.REP,
        weeks.WkNum,
        weeks.amount
 FROM #Budget bud
 CROSS APPLY 
 (VALUES (1, bud.WK1),
         (2, bud.WK2),
         (3, bud.WK3),
         (4, bud.WK4)
   ) AS weeks(WkNum, amount)
   ORDER BY bud.COMPANY, bud.REP, weeks.WkNum

   DROP TABLE #Budget