两列中的六列

时间:2013-08-01 22:39:36

标签: sql sql-server pivot

这是我需要在SQL Report

中创建的报告

3列SwingTurnbackInday是帐户发出的批量请求类型。它们存储在VolumeRequest表中,该表存储按帐户的请求以及请求的开始和结束日期,如下所示Volme Request

VolumeRequestTypeId 2代表Swing,3代表Turnback,4代表Inday

3列FL Gas Zn1 (GDA)FL Gas Zn2 (GDA)FL Gas Zn3 (GDA)以及每日价格(Midpoint)的索引存储在IndexHistory表中,如下{{0 }}

我需要显示与账户相关的各种交易量请求202,203,205  一个月。该报告必须在该月的每一天都有一行,因此我需要总结每种类型的卷请求的一天请求

为了达到这个目的,我开始应用solution我在两个表中找到两次,如下所示

    DECLARE @startdate DATE
    SET @startdate = '03/01/2013'

    SELECT  DISTINCT IH.Flowdate AS [Date],
            CASE WHEN VR.VolumeRequestTypeId=2 AND IH.Flowdate BETWEEN VR.StartDate AND VR.EndDate THEN SUM(VR.Volume) END AS Swing,
            CASE WHEN VR.VolumeRequestTypeId=3 AND IH.Flowdate BETWEEN VR.StartDate AND VR.EndDate THEN SUM(VR.Volume) END AS Turnback,
            CASE WHEN VR.VolumeRequestTypeId=4 AND IH.Flowdate BETWEEN VR.StartDate AND VR.EndDate THEN SUM(VR.Volume) END AS Inday,
            CASE WHEN IH.Indexid=412 THEN IH.Midpoint END AS [FL Gas Zn1 (GDA)],
            CASE WHEN IH.Indexid=420 THEN IH.Midpoint END AS [FL Gas Zn2 (GDA)],
            CASE WHEN IH.Indexid=463 THEN IH.Midpoint END AS [FL Gas Zn3 (GDA)]
    FROM IndexHistory IH
    LEFT JOIN VolumeRequest VR 
    ON IH.FlowDate BETWEEN @startdate AND EOMONTH(@startdate,0) AND indexid in (412,463,420) AND VR.EndDate>= @startdate AND VR.StartDate <= EOMONTH(@startdate,0) 
    INNER JOIN  Account A 
    ON A.Id=VR.accountId
    INNER JOIN VolumeRequestType VRT 
    ON VR.VolumeRequestTypeId=VRT.Id
    WHERE VRT.Id in (2,3,4) AND ISNULL(VR.Deprecated,0)<>1 AND A.Id in (202,203,205) AND ISNULL(A.Status,'open')<>'closed'
    GROUP BY VR.VolumeRequestTypeId, IH.Flowdate, VR.Volume, IH.Indexid, IH.Midpoint,VR.StartDate,VR.EndDate 
    ORDER BY  [Date]

但是它返回了下面的表Index History

由于不是必需的结果,我为这三个索引的IndexHistory做了3次连接,如下所示

DECLARE @startdate DATE
SET @startdate = '03/01/2013'

SELECT DISTINCT IH1.Flowdate AS [Date],
              CASE WHEN VR.VolumeRequestTypeId=2 AND IH1.Flowdate BETWEEN VR.StartDate AND VR.EndDate THEN SUM(VR.Volume) END AS Swing,
              CASE WHEN VR.VolumeRequestTypeId=3 AND IH1.Flowdate BETWEEN VR.StartDate AND VR.EndDate THEN SUM(VR.Volume) END AS Turnback,
              CASE WHEN VR.VolumeRequestTypeId=4 AND IH1.Flowdate BETWEEN VR.StartDate AND VR.EndDate THEN SUM(VR.Volume) END AS Inday,
              IH1.Midpoint AS [FL Gas Zn1 (GDA)],
              IH2.Midpoint AS [FL Gas Zn2 (GDA)],
              IH3.Midpoint AS [FL Gas Zn3 (GDA)]
FROM IndexHistory IH1
LEFT JOIN VolumeRequest VR ON IH1.FlowDate BETWEEN @startdate AND EOMONTH(@startdate,0) AND IH1.indexid = 412 AND VR.EndDate>= @startdate AND VR.StartDate <= EOMONTH(@startdate,0) 
INNER JOIN IndexHistory IH2 ON IH2.FlowDate = IH1.FlowDate AND IH2.indexid = 420
INNER JOIN IndexHistory IH3 ON IH3.FlowDate = IH1.FlowDate AND IH3.indexid = 463
INNER JOIN  Account A ON A.Id=VR.accountId
INNER JOIN VolumeRequestType VRT ON VR.VolumeRequestTypeId=VRT.Id
WHERE VRT.Id in (2,3,4) AND ISNULL(VR.Deprecated,0)<>1 AND A.Id in (202,203,205) AND ISNULL(A.Status,'open')<>'closed'
GROUP BY VR.VolumeRequestTypeId, IH1.Flowdate, VR.Volume, IH1.Midpoint,IH2.Midpoint, IH3.Midpoint, VR.StartDate,VR.EndDate 
ORDER BY  [Date]

这会返回以下结果result1

由于GROUP BY,我的音量总和超出了要求。我想尝试`OVER'并尝试下面的

DECLARE @startdate DATE
SET @startdate = '03/01/2013'

SELECT DISTINCT IH1.Flowdate AS [Date],
        CASE WHEN VR.VolumeRequestTypeId=2 AND IH1.Flowdate BETWEEN VR.StartDate AND VR.EndDate THEN  SUM(VR.Volume) OVER (PARTITION BY IH1.Flowdate) END AS Swing,
        CASE WHEN VR.VolumeRequestTypeId=3 AND IH1.Flowdate BETWEEN VR.StartDate AND VR.EndDate THEN  SUM(VR.Volume) OVER (PARTITION BY IH1.Flowdate) END AS Turnback,
        CASE WHEN VR.VolumeRequestTypeId=4 AND IH1.Flowdate BETWEEN VR.StartDate AND VR.EndDate THEN  SUM(VR.Volume) OVER (PARTITION BY IH1.Flowdate) END AS Inday,
        IH1.Midpoint AS [FL Gas Zn1 (GDA)],
        IH2.Midpoint AS [FL Gas Zn2 (GDA)],
        IH3.Midpoint AS [FL Gas Zn3 (GDA)]
FROM IndexHistory IH1
LEFT JOIN VolumeRequest VR ON IH1.FlowDate BETWEEN @startdate AND EOMONTH(@startdate,0) AND IH1.indexid = 412 AND VR.EndDate>= @startdate AND VR.StartDate <= EOMONTH(@startdate,0) 
INNER JOIN IndexHistory IH2 ON IH2.FlowDate = IH1.FlowDate AND IH2.indexid = 420
INNER JOIN IndexHistory IH3 ON IH3.FlowDate = IH1.FlowDate AND IH3.indexid = 463
INNER JOIN  Account A ON A.Id=VR.accountId
INNER JOIN VolumeRequestType VRT ON VR.VolumeRequestTypeId=VRT.Id
WHERE VRT.Id in (2,3,4) AND ISNULL(VR.Deprecated,0)<>1 AND A.Id in (202,203,205) AND ISNULL(A.Status,'open')<>'closed' AND IH1.Flowdate BETWEEN VR.StartDate AND VR.EndDate
ORDER BY  [Date]

这一次是正确的,期望没有请求的那些日子不显示在result2下面  我不知道我哪里出错了。有人可以帮我这个吗?

1 个答案:

答案 0 :(得分:2)

我首先要说的是,通过提供不匹配的数据,您已经做到了难以置信的难度 - 第一张图片有2013年3月的数据,第二张图片是6月12日,第三张图片是7月12日。因此,它很难弄清楚数据来自何处以及如何应用数据。

无论如何,这就是我想出来的。我没有包含帐户表(或通过帐户限制),所以如果您选择使用它,则必须进行一些修改

;WITH Gas AS (
  SELECT FlowDate, [412] as [FL Gas Zn1 (GDA)], [463] as [FL Gas Zn2 (GDA)], [420] as [FL Gas Zn3 (GDA)]
  FROM (
    SELECT IndexId, FlowDate, Midpoint
    FROM IndexHistory
  ) p
  PIVOT (max(Midpoint) FOR IndexId IN ([412], [463], [420])) AS pvt
), 
Volume AS (
  SELECT FlowDate, [Swing], [Turnback], [Inlay]
  FROM (
    SELECT DISTINCT IH.Flowdate, VRT.Name, VR.Volume
    FROM IndexHistory IH
    INNER JOIN VolumeRequest VR ON IH.FlowDate BETWEEN @startdate AND '2012-06-30' AND indexid IN (412,463,420) AND VR.EndDate>= @startdate AND VR.StartDate <= '2012-06-30'
    INNER JOIN VolumeRequestType VRT ON VR.VolumeRequestTypeId = VRT.Id
  ) p
  PIVOT (sum(Volume) FOR Name IN ([Swing], [Turnback], [Inlay])) AS pvt
)
SELECT G.Flowdate, Swing, Turnback, Inlay, [FL Gas Zn1 (GDA)], [FL Gas Zn2 (GDA)], [FL Gas Zn3 (GDA)]
FROM Gas G
INNER JOIN Volume V ON G.FlowDate = V.FlowDate

我已经广泛使用PIVOTsCTEs来实现此目标

SQL Fiddle here