簡體   English   中英

有“總計”列時如何使用 Pivot?

[英]How do I use Pivot when there's a 'Totals' column?

我整理了一個查詢,該查詢顯示了/年的井數,並在名為“總計”的列中匯總了它們的總數。 有關工作查詢,請參閱帖子底部的 db<>fiddle 鏈接。

SELECT
    YEAR(wd.eventdate) AS [Year],
    ISNULL(COUNT(DISTINCT w_oil.WellID), 0) AS [Oil Wells],
    ISNULL(COUNT(DISTINCT w_gas.WellID), 0) AS [Gas Wells],
    ISNULL(COUNT(DISTINCT w_service.WellID), 0) AS [Service Wells],
    ISNULL(COUNT(DISTINCT w_dry.WellID), 0) AS [Dry Holes],
    ISNULL(COUNT(DISTINCT w_tot.WellID), 0) AS [Totals]
FROM HWellDate wd
    LEFT JOIN HWell w_oil ON (w_oil.PKey = wd.WellKey and w_oil.WellType = 'OW')
    LEFT JOIN HWell w_gas ON (w_gas.PKey = wd.WellKey and w_gas.WellType = 'GW')
    LEFT JOIN HWell w_service ON
    (
    w_service.PKey = wd.WellKey
    AND w_service.WellType IN ('WI','GI','GS','WD','WS','TW')
    )
    LEFT JOIN HWell w_dry ON (w_dry.PKey = wd.WellKey and w_dry.WellType = 'D')
    LEFT JOIN HWell w_tot ON w_tot.PKey = wd.WellKey
WHERE wd.comment = 'PA'
    AND wd.event = 'WELLSTATUS'
    AND (YEAR(wd.eventdate) >= (YEAR(GETDATE()) - 4) AND YEAR(wd.eventdate) <= YEAR(GETDATE()))
GROUP BY YEAR(wd.eventdate)

查詢有效,但我想轉置表格,以便年份作為列名列在頂部,總計列是底部的一行。

這是從上面的查詢生成的表:

油井 氣井 服務井 干洞 總計
2017年 6 7 1 1 15
2018年 15 23 5 6 49
2019年 7 6 4 5 22
2020年 10 16 4 0 30
2021年 24 23 3 3 53

這是我想要的:

井型 2021年 2020年 2019年 2018年 2017年
油井 24 10 7 15 6
氣井 23 16 6 23 7
服務井 3 4 4 5 1
干洞 3 0 5 6 1
總計 53 30 22 49 15

我想我需要使用PIVOT來旋轉表格,但我懷疑我可能還需要使用UNPIVOT來獲得我正在尋找的結果。 我想我可以將第一個表中的數據插入到名為“#wellsPluggedTempTbl”的臨時表中。 之后,也許我可以使用動態sql來生成結果。

這是我到目前為止所擁有的:

DECLARE @colsPivot AS NVARCHAR(MAX)
DECLARE @query  AS NVARCHAR(MAX)

INSERT INTO #wellsPluggedTempTbl([Year], [Oil Wells], [Gas Wells], [Service Wells], [Dry Holes], Totals)
SELECT
    YEAR(wd.eventdate) AS [Year],
    ISNULL(COUNT(DISTINCT w_oil.WellID), 0) AS [Oil Wells],
    ISNULL(COUNT(DISTINCT w_gas.WellID), 0) AS [Gas Wells],
    ISNULL(COUNT(DISTINCT w_service.WellID), 0) AS [Service Wells],
    ISNULL(COUNT(DISTINCT w_dry.WellID), 0) AS [Dry Holes],
    ISNULL(COUNT(DISTINCT w_tot.WellID), 0) AS [Totals]
FROM HWellDate wd
    LEFT JOIN HWell w_oil ON (w_oil.PKey = wd.WellKey and w_oil.WellType = 'OW')
    LEFT JOIN HWell w_gas ON (w_gas.PKey = wd.WellKey and w_gas.WellType = 'GW')
    LEFT JOIN HWell w_service ON
    (
    w_service.PKey = wd.WellKey
    AND w_service.WellType IN ('WI','GI','GS','WD','WS','TW')
    )
    LEFT JOIN HWell w_dry ON (w_dry.PKey = wd.WellKey and w_dry.WellType = 'D')
    LEFT JOIN HWell w_tot ON w_tot.PKey = wd.WellKey
WHERE wd.comment = 'PA'
    AND wd.event = 'WELLSTATUS'
    AND (YEAR(wd.eventdate) >= (YEAR(GETDATE()) - 4) AND YEAR(wd.eventdate) <= YEAR(GETDATE()))
GROUP BY YEAR(wd.eventdate)

但是,我在運行上述命令后收到此錯誤:“無效的對象名稱‘#wellsPluggedTempTbl’。

對於最后的井型排序,我知道我需要使用這樣的CASE WHEN語句:

ORDER BY
    CASE WellType
        WHEN 'Totals' THEN 5
        WHEN 'Dry Holes' THEN 4
        WHEN 'Service Wells' THEN 3
        WHEN 'Gas Wells' THEN 2
        WHEN 'Oil Wells' THEN 1
    END

是一個指向 db<>fiddle 的鏈接,我在其中收集了在這篇文章中產生結果的數據樣本。 任何幫助,將不勝感激! 謝謝。

你正在接近這個錯誤。 您應該只使用條件聚合,而不是旋轉現有查詢。

注意其他效率

  • 無需多次加入。 只需加入一次並使用CASE表達式
  • 注意使用CROSS APPLY (VALUES來創建和重用分組表達式
  • 使用GROUPING SETSROLLUP獲取總計行,使用GROUPING()函數來標識該行
  • 不要在WHERE列上使用函數,而是創建您需要的日期范圍並對其進行過濾。
  • 如果您需要動態年份,而不是使用動態 SQL,只需調用列ThisYear LastYear
SELECT
  WellType = CASE WHEN GROUPING(v.WellType) = 0 THEN v.WellType ELSE 'Totals' END,
  [2021] = COUNT(CASE WHEN [Year] = 2021 THEN 1 END),
  [2020] = COUNT(CASE WHEN [Year] = 2020 THEN 1 END),
  [2019] = COUNT(CASE WHEN [Year] = 2019 THEN 1 END),
  [2018] = COUNT(CASE WHEN [Year] = 2018 THEN 1 END),
  [2017] = COUNT(CASE WHEN [Year] = 2017 THEN 1 END)
FROM HWellDate wd
JOIN HWell w ON w.PKey = wd.WellKey
CROSS APPLY (VALUES(
    CASE WHEN w.WellType = 'OW' THEN 'Oil Wells'
         WHEN w.WellType = 'GW' THEN 'Gas Wells'
         WHEN w.WellType IN ('WI','GI','GS','WD','WS','TW') THEN 'Service Wells'
         WHEN w.WellType = 'D' THEN 'Dry Holes'
    END,
    YEAR(wd.eventdate)
)) v(WellType, Year)
WHERE wd.comment = 'PA'
  AND wd.event = 'WELLSTATUS'
  AND wd.eventdate >= DATEFROMPARTS(YEAR(GETDATE()) - 4, 1, 1)
  AND wd.eventdate <  DATEFROMPARTS(YEAR(GETDATE()) + 1, 1, 1)
GROUP BY GROUPING SETS (
    (v.WellType),
    ()
 )
ORDER BY GROUPING(v.WellType) DESC,
    CASE v.WellType
        WHEN 'Dry Holes' THEN 4
        WHEN 'Service Wells' THEN 3
        WHEN 'Gas Wells' THEN 2
        WHEN 'Oil Wells' THEN 1
    END
;

數據庫<>小提琴

如果您首先按井類型和年份分組,那么在外部查詢中進行透視會變得更容易。

由於孔類別已經可以在子查詢中計算出來。

並且通過匯總和條件總和分組,它還將獲得總數。

SELECT ISNULL(q.HoleCategory, 'Total') AS WellType
, SUM(CASE WHEN q.eventYear=2021 THEN q.Total END) AS [2021]
, SUM(CASE WHEN q.eventYear=2020 THEN q.Total END) AS [2020]
, SUM(CASE WHEN q.eventYear=2019 THEN q.Total END) AS [2019]
, SUM(CASE WHEN q.eventYear=2018 THEN q.Total END) AS [2018]
, SUM(CASE WHEN q.eventYear=2017 THEN q.Total END) AS [2017]
FROM
(
    SELECT w.WellType
    , YEAR(wd.eventDate) AS eventYear
    ,CASE 
     WHEN w.WellType = 'OW' THEN 'Oil Wells'
     WHEN w.WellType = 'GW' THEN 'Gas Wells'
     WHEN w.WellType IN ('WI','GI','GS','WD','WS','TW') THEN 'Service Wells'
     WHEN w.WellType = 'D' THEN 'Dry Holes'
     END AS HoleCategory 
    , COUNT(DISTINCT w.WellID) AS Total
    FROM HWellDate wd
    LEFT JOIN HWell w ON w.PKey = wd.WellKey
    WHERE wd.comment = 'PA'
      AND wd.event = 'WELLSTATUS'
      AND w.WellType IS NOT NULL
      AND YEAR(wd.eventdate) BETWEEN 2017 AND 2021
    GROUP BY w.WellType, YEAR(wd.eventDate)
) q
GROUP BY ROLLUP(q.HoleCategory)
ORDER BY
    CASE q.HoleCategory
    WHEN 'Oil Wells' THEN 1
    WHEN 'Gas Wells' THEN 2
    WHEN 'Service Wells' THEN 3
    WHEN 'Dry Holes' THEN 4
    ELSE 9
    END

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM