Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL查询转换表_Sql_Sql Server_Pivot - Fatal编程技术网

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

我有一个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       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