我正在尝试使用多个列,我正在使用SQL Server 2014,但是,我无法弄清楚如何做到这一点。这是我到目前为止所尝试的内容:
DECLARE @Table TABLE (
Name NVARCHAR(MAX),
TypeId INT,
TotalOrders INT,
GrandTotal MONEY
)
INSERT INTO @Table
(Name, TypeId, TotalOrders, GrandTotal)
VALUES
('This Month', 1, 10, 1),
('This Month', 2, 5, 7),
('This Week', 1, 8, 3),
('Last Week', 1, 8, 12),
('Yesterday', 1, 10, 1),
('Yesterday', 2, 1, 5)
产生以下结果:
Name TypeId TotalOrders GrandTotal
-------------------------------- ----------- ----------- ---------------------
This Month 1 10 1.00
This Month 2 5 7.00
This Week 1 8 3.00
Last Week 1 8 12.00
Yesterday 1 10 1.00
Yesterday 2 1 5.00
要将这些行放入列中,我试过这个:
SELECT
TypeId,
ISNULL([Yesterday], 0) AS YesterdayTotalOrders,
ISNULL([This Week], 0) AS ThisWeekTotalOrders,
ISNULL([Last Week], 0) AS LastWeekTotalOrders,
ISNULL([This Month], 0) AS ThisMonthTotalOrders
FROM
(SELECT Name, TypeId, TotalOrders FROM @Table) AS src
PIVOT (
SUM(TotalOrders) FOR Name IN (
[Yesterday],
[This Week],
[Last Week],
[This Month]
)
) AS p1
产生以下结果集:
TypeId YesterdayTotalOrders ThisWeekTotalOrders LastWeekTotalOrders ThisMonthTotalOrders
----------- -------------------- ------------------- ------------------- --------------------
1 10 8 8 10
2 1 0 0 5
现在,我需要为GrandTotal
添加其他几列,例如YesterdayGrandTotal
,ThisWeekGrandTotal
等等,但我无法弄清楚如何实现这一目标。
任何帮助都将受到高度赞赏。
更新#1:这是预期的结果集:
TypeId YesterdayTotalOrders ThisWeekTotalOrders LastWeekTotalOrders ThisMonthTotalOrders YesterdayGrandTotal ThisWeekGrandTotal LastWeekGrandTotal ThisMonthGrandTotal
----------- -------------------- ------------------- ------------------- -------------------- --------------------- --------------------- --------------------- ---------------------
1 10 8 8 10 1.00 3.00 12.00 1.00
2 1 0 0 5 5.00 0.00 0.00 7.00
答案 0 :(得分:1)
条件聚合可能是一个解决方案:
select typeID,
SUM(case when name = 'Yesterday' then totalOrders else 0 end) as YesterdayTotalOrders,
SUM(case when name = 'This Week' then totalOrders else 0 end) as ThisWeekTotalOrders,
SUM(case when name = 'Last Week' then totalOrders else 0 end) as LastWeekTotalOrders,
SUM(case when name = 'This Month' then totalOrders else 0 end) as ThisMonthTotalOrders,
SUM(case when name = 'Yesterday' then GrandTotal else 0 end) as YesterdayGrandTotal,
SUM(case when name = 'This Week' then GrandTotal else 0 end) as ThisWeekGrandTotal,
SUM(case when name = 'Last Week' then GrandTotal else 0 end) as LastWeekGrandTotal,
SUM(case when name = 'This Month' then GrandTotal else 0 end) as ThisMonthGrandTotal
from @table
group by typeID
或者,您可以像这样使用CROSS APPLY
和PIVOT
SELECT
TypeId,
ISNULL([Yesterday], 0) AS YesterdayTotalOrders,
ISNULL([This Week], 0) AS ThisWeekTotalOrders,
ISNULL([Last Week], 0) AS LastWeekTotalOrders,
ISNULL([This Month], 0) AS ThisMonthTotalOrders,
ISNULL([grant Yesterday], 0) AS YesterdayGrandTotal,
ISNULL([grant This Week], 0) AS ThisWeekGrandTotal,
ISNULL([grant Last Week], 0) AS LastWeekGrandTotal,
ISNULL([grant This Month], 0) AS ThisMonthGrandTotal
FROM
(
SELECT t.*
FROM @Table
CROSS APPLY (values(Name, TypeId, TotalOrders),
('grant ' + Name, TypeId, GrandTotal))
t(Name, TypeId, TotalOrders)
) AS src
PIVOT (
SUM(TotalOrders) FOR Name IN (
[Yesterday],
[This Week],
[Last Week],
[This Month],
[grant Yesterday],
[grant This Week],
[grant Last Week],
[grant This Month]
)
) AS p1
两种解决方案都只扫描输入表一次,它们的查询计划非常相似。两种解决方案都优于两个枢轴JOIN
(我最初提供的解决方案),因为两个枢轴需要扫描输入表两次。
答案 1 :(得分:1)
您也可以将pivots
P1
TotalOrders
与P2
分开来使用GrandTotal
。 ;WITH CTE AS
(
SELECT
P1.TypeId,
ISNULL(P1.[Yesterday], 0) AS YesterdayTotalOrders,
ISNULL(P1.[This Week], 0) AS ThisWeekTotalOrders,
ISNULL(P1.[Last Week], 0) AS LastWeekTotalOrders,
ISNULL(P1.[This Month], 0) AS ThisMonthTotalOrders
FROM
(SELECT Name, TypeId, TotalOrders FROM @Table) AS src
PIVOT (SUM(TotalOrders) FOR src.Name IN (
[Yesterday],
[This Week],
[Last Week],
[This Month])) AS P1
), CTE1 AS
(
SELECT
P1.TypeId,
ISNULL(P1.[Yesterday], 0) AS YesterdayGrandTotal,
ISNULL(P1.[This Week], 0) AS ThisWeekTGrandTotal,
ISNULL(P1.[Last Week], 0) AS LastWeekGrandTotal,
ISNULL(P1.[This Month], 0) AS ThisMonthGrandTotal
FROM
(SELECT Name, TypeId, GrandTotal FROM @Table) AS src
PIVOT (SUM(GrandTotal) FOR src.Name IN (
[Yesterday],
[This Week],
[Last Week],
[This Month])) AS P1
)
SELECT C.TypeId , C.YesterdayTotalOrders, C.ThisWeekTotalOrders, C.LastWeekTotalOrders, C.ThisMonthTotalOrders , C1.YesterdayGrandTotal , C1.ThisWeekTGrandTotal ,C1.LastWeekGrandTotal , C1.ThisMonthGrandTotal FROM CTE C
INNER JOIN CTE1 C1 ON C1.TypeId = C.TypeId
TypeId YesterdayTotalOrders ThisWeekTotalOrders LastWeekTotalOrders ThisMonthTotalOrders YesterdayGrandTotal ThisWeekGrandTotal LastWeekGrandTotal ThisMonthGrandTotal
----------- -------------------- ------------------- ------------------- -------------------- --------------------- --------------------- --------------------- ---------------------
1 10 8 8 10 1.00 3.00 12.00 1.00
2 1 0 0 5 5.00 0.00 0.00 7.00
public enum ValidityTypes : int
{
[Description("Not Set")]
None = 0,
[Description("Zero Validity")]
ZeroValidity = 1,
[Description("Life Time Validity")]
LifeTimeValidity = 2,
[Description("N Months")]
NMonths = 3,
[Description("Rehire Validity in Months")]
RehireValidity = 4
}
结果:
public ValidityTypes ValidityType { get; set; }
答案 2 :(得分:0)
在oracle我会做类似的东西。它适用于我
select * from (
SELECT Name, TypeId,TotalOrders
--hier
,GrandTotal
FROM test_b )
PIVOT ( SUM(TotalOrders)TotalOrders,
--hier
SUM(grandtotal) grandtotal FOR Name IN
('Yesterday'Yesterday,'This Week'ThisWeek,'Last Week'LastWeek,'This
Month'ThisMonth )
) ;
所以在sql server中尝试这个
SELECT *
/* TypeId,
ISNULL([Yesterday], 0) AS YesterdayTotalOrders,
ISNULL([This Week], 0) AS ThisWeekTotalOrders,
ISNULL([Last Week], 0) AS LastWeekTotalOrders,
ISNULL([This Month], 0) AS ThisMonthTotalOrders*/
FROM
(SELECT Name, TypeId, TotalOrders
,grandtotal
FROM @Table) AS src
PIVOT (
SUM(TotalOrders)TotalOrders, SUM(grandtotal)grandtotal FOR Name IN (
[Yesterday]Yesterday,
[This Week]ThisWeek,
[Last Week]LastWeek,
[This Month]ThisMonth
)
) AS p1