SQL查询转换表
我有一个sql查询,它从几个表中选择数据并进行一些计算。它产生的结果如下所示:SQL查询转换表,sql,sql-server,pivot,Sql,Sql Server,Pivot,我有一个sql查询,它从几个表中选择数据并进行一些计算。它产生的结果如下所示: year month avg region 2011 1 123 UK 2012 1 0 UK 2013 1 0 UK 2011 2 400 UK 2012 2 200 UK 2013 2 0 UK month year1 year2 year3 region 1
year month avg region
2011 1 123 UK
2012 1 0 UK
2013 1 0 UK
2011 2 400 UK
2012 2 200 UK
2013 2 0 UK
month year1 year2 year3 region
1 123 0 0 UK
2 400 200 0 UK
但我希望结果是这样的:
year month avg region
2011 1 123 UK
2012 1 0 UK
2013 1 0 UK
2011 2 400 UK
2012 2 200 UK
2013 2 0 UK
month year1 year2 year3 region
1 123 0 0 UK
2 400 200 0 UK
以下是我当前的查询:
SELECT TOP (100) PERCENT DATEPART(YEAR, dbo.Fixtures.Date) AS YEAR,
DATEPART(MONTH, dbo.Fixtures.Date) AS MONTH,
AVG(dbo.Fixtures.PCRate) AS AveragePCRate,
dbo.Region.GroupName AS Region
FROM dbo.Fixtures
INNER JOIN dbo.Vessel ON dbo.Fixtures.VesselId = dbo.Vessel.ID
INNER JOIN dbo.Region ON dbo.Fixtures.RegionId = dbo.Region.ID
WHERE (YEAR(dbo.Fixtures.Date) >= YEAR(DATEADD(YEAR, - 2, GETDATE())))
AND (dbo.Vessel.TypeId = 1)
AND (dbo.Vessel.Total_BHP >= 15000)
AND (dbo.Vessel.Total_BHP < 20000)
GROUP BY dbo.Region.GroupName,
DATEPART(YEAR, dbo.Fixtures.Date),
DATEPART(MONTH, dbo.Fixtures.Date)
ORDER BY YEAR, MONTH
这是我在执行下面建议的piv查询时得到的结果:
m year1 year2 year3 region
1 NULL 0 8500 Norway
2 NULL NULL NULL Norway
3 NULL NULL NULL Norway
4 NULL NULL NULL Norway
5 NULL NULL NULL Norway
6 NULL NULL NULL Norway
7 NULL NULL NULL Norway
8 NULL NULL NULL Norway
9 NULL NULL NULL Norway
10 NULL NULL NULL Norway
11 NULL NULL NULL Norway
12 NULL NULL NULL Norway
3 NULL NULL NULL South America
1 10250 6000 13000 United Kingdom
2 NULL NULL NULL United Kingdom
3 NULL NULL NULL United Kingdom
4 NULL NULL NULL United Kingdom
5 NULL NULL NULL United Kingdom
6 NULL NULL NULL United Kingdom
7 NULL NULL NULL United Kingdom
8 NULL NULL NULL United Kingdom
9 NULL NULL NULL United Kingdom
10 NULL NULL NULL United Kingdom
11 NULL NULL NULL United Kingdom
12 NULL NULL NULL United Kingdom
您没有指定正在使用的RDBMS,但由于您使用的是TOP,我猜是SQL Server 在SQL Server中,可以使用PIVOT函数转换数据:
SELECT month,
[2011] as year1,
[2012] as year2,
[2013] as year3,
region
FROM
(
SELECT DATEPART(year, dbo.Fixtures.Date) AS Year,
DATEPART(Month, dbo.Fixtures.Date) AS Month,
dbo.Fixtures.PCRate,
dbo.Region.GroupName AS Region
FROM dbo.Fixtures
INNER JOIN dbo.Vessel
ON dbo.Fixtures.VesselId = dbo.Vessel.ID
INNER JOIN dbo.Region
ON dbo.Fixtures.RegionId = dbo.Region.ID
WHERE (YEAR(dbo.Fixtures.Date) >= YEAR(DATEADD(year, - 2, GETDATE())))
AND (dbo.Vessel.TypeId = 1)
AND (dbo.Vessel.Total_BHP >= 15000)
AND (dbo.Vessel.Total_BHP < 20000)
) src
pivot
(
avg(PCRate)
for year in ([2011], [2012], [2013])
) piv;
尝试:
您可以让CASE语句使用当前日期进行测试,这样您一次只有三年时间。您好,是的,我使用的是SQL Server。对不起,我忘记提了。我尝试了您的第一个解决方案,它完全符合我的要求,但我不想硬编码这些值。当我尝试第二种解决方案时,我得到错误:无效列名“year”,位于“year”+castrow_number,按DATEPARTyear超额分配,dbo.Fixtures.Date order by DATEPARTy…很抱歉,使用pivot方法计算不正确。我猜平均值的计算方式有所不同,因为它是在表格翻转后完成的。@linnkb您能用每个表格中的样本数据编辑您的原始帖子吗?我已经为原始查询和使用时添加了样本数据piv@linnkb请看我的编辑。如果这没有帮助,那么我建议使用原始表和一些示例数据创建一个。您提供的示例数据是查询的结果,因此更容易查看每个表中的示例数据。
select month, [2011] as year1, [2012] as year2, [2013] as year3, region
from
(
SELECT
DATEPART(YEAR, dbo.Fixtures.Date) AS YEAR,
DATEPART(MONTH, dbo.Fixtures.Date) AS MONTH,
AVG(dbo.Fixtures.PCRate) AS AveragePCRate,
dbo.Region.GroupName AS Region
FROM dbo.Fixtures
INNER JOIN dbo.Vessel ON dbo.Fixtures.VesselId = dbo.Vessel.ID
INNER JOIN dbo.Region ON dbo.Fixtures.RegionId = dbo.Region.ID
WHERE (YEAR(dbo.Fixtures.Date) >= YEAR(DATEADD(YEAR, - 2, GETDATE())))
AND (dbo.Vessel.TypeId = 1)
AND (dbo.Vessel.Total_BHP >= 15000)
AND (dbo.Vessel.Total_BHP < 20000)
GROUP BY dbo.Region.GroupName,
DATEPART(YEAR, dbo.Fixtures.Date),
DATEPART(MONTH, dbo.Fixtures.Date)
) src
pivot
(
max(AveragePCRate)
for YEAR in ([2011], [2012], [2013])
) piv;
SELECT
Month
,MAX(CASE WHEN YEAR = 2011 THEN AveragePCRate ELSE Null END) AS Year1
,MAX(CASE WHEN YEAR = 2012 THEN AveragePCRate ELSE Null END) AS Year2
,MAX(CASE WHEN YEAR = 2013 THEN AveragePCRate ELSE Null END) AS Year3
,Region
FROM
(
SELECT TOP (100) PERCENT DATEPART(YEAR, dbo.Fixtures.Date) AS YEAR,
DATEPART(MONTH, dbo.Fixtures.Date) AS MONTH,
AVG(dbo.Fixtures.PCRate) AS AveragePCRate,
dbo.Region.GroupName AS Region
FROM dbo.Fixtures
INNER JOIN dbo.Vessel ON dbo.Fixtures.VesselId = dbo.Vessel.ID
INNER JOIN dbo.Region ON dbo.Fixtures.RegionId = dbo.Region.ID
WHERE (YEAR(dbo.Fixtures.Date) >= YEAR(DATEADD(YEAR, - 2, GETDATE())))
AND (dbo.Vessel.TypeId = 1)
AND (dbo.Vessel.Total_BHP >= 15000)
AND (dbo.Vessel.Total_BHP < 20000)
GROUP BY dbo.Region.GroupName,
DATEPART(YEAR, dbo.Fixtures.Date),
DATEPART(MONTH, dbo.Fixtures.Date)
) YourQuery
GROUP BY Month, Region