【问题标题】:How/where do I use PIVOT?我如何/在哪里使用 PIVOT?
【发布时间】:2021-09-20 17:49:54
【问题描述】:

我有一个数据表,其中显示单个数据的多行。在下面的示例中,我有一个名为“Location Type”的列,其中显示“BH”和“TPI”。 BH 和 TPI 各有一个特定的位置,显示在“位置”列中。我想要两个新列来显示该行的位置数据,而不是为 BH 和 TPI 设置一个新行。我在下面包含了几行数据。我怀疑我需要在这里使用 PIVOT,但我一直很难弄清楚 PIVOT 需要进入的位置。有人可以提供一些指导或向我展示解决方案吗?

这是来自查询的数据示例。

API14 First Prod Date Location Type Location
43013540070000 2/8/2021 BH Township 3S Range 4W Section 17 DUCHESNE County
43013540070000 2/8/2021 TPI Township 3S Range 4W Section 18 DUCHESNE County

这是我希望看到的格式:

API14 First Prod Date BH Location TPI Location
43013540070000 2/8/2021 Township 3S Range 4W Section 17 DUCHESNE County Township 3S Range 4W Section 18 DUCHESNE County

到目前为止,这是我的代码:

DECLARE @SearchYear AS VARCHAR(4) = '2021'
DECLARE @SearchMonth AS VARCHAR(2) = '6'

SELECT
    dbo.BuildAPI14(Well.WellID, Construct.SideTrack, Construct.Completion) AS 'API14',
    CAST(ConstructDate.EventDate AS DATE) AS 'First Prod Date',
    Loc.LocType AS 'Location Type',
    CONCAT('Township ',LocExt.Township,LocExt.TownshipDir,' ','Range ',LocExt.Range,LocExt.RangeDir,' Section ',LocExt.Sec,' ',RefCounty.CountyName,' County') AS 'Location',
    tblAPDTracker.SpacingRule AS 'Spacing Rule',
    Lease.Number AS 'Entity Number',
    WellHistory.WHComments AS 'Well History Comments'
FROM Well
    LEFT JOIN Construct ON Construct.WellKey = Well.PKey
    LEFT JOIN ConstructReservoir ON ConstructReservoir.ConstructKey = Construct.PKey
    LEFT JOIN Lease ON Lease.Pkey = ConstructReservoir.LeaseKey
    LEFT JOIN WellHistory ON WellHistory.WellKey = Construct.WellKey
    LEFT JOIN tblAPDTracker ON LEFT(tblAPDTracker.APINO,10) = Well.WellID
    LEFT JOIN Loc ON loc.ConstructKey = Construct.PKey AND Loc.LocType IN ('BH','TPI')
    LEFT JOIN LocExt ON LocExt.LocKey = Loc.PKey
    LEFT JOIN ConstructDate ON ConstructDate.ConstructKey = Construct.PKey AND ConstructDate.Event = 'FirstProduction'
    LEFT JOIN RefCounty ON RefCounty.PKey = LocExt.County
WHERE
    WorkType = 'ENTITY' AND
    WellHistory.ModifyUser = 'UTAH\rachelmedina' AND
    YEAR(WellHistory.ModifyDate) = @SearchYear AND
    MONTH(WellHistory.ModifyDate) = @SearchMonth
GROUP BY
    Well.WellID,
    Construct.SideTrack,
    Construct.Completion,
    ConstructDate.EventDate,
    Loc.LocType,
    LocExt.Township,
    LocExt.TownshipDir,
    LocExt.Range,
    LocExt.RangeDir,
    LocExt.Sec,
    RefCounty.CountyName,
    tblAPDTracker.SpacingRule,
    Lease.Number,
    WellHistory.WHComments,
    WellHistory.ModifyDate
ORDER BY
    Well.WellId,
    WellHistory.ModifyDate DESC

【问题讨论】:

  • 助您一臂之力_minimal reproducible example
  • @jarlh 我正在尝试将示例中的数据添加到表格中,以便任何人都可以获取它。它在我的编辑中看起来不错,但是一旦我点击保存它就会变成乱码。我会继续努力,看看我是否可以进一步简化。
  • 这里的大多数人都希望样本表数据_和预期结果为格式化文本,而不是图像。 (而且我什至无法阅读那个微小的图像文本......)
  • @jarlh 我将添加一些示例数据以及我希望看到的结果。
  • @jarlh 我可以对这篇文章做些什么来获得更多回复吗?我添加了一些示例数据和预期的结果。我还缩短了查询以针对示例数据。

标签: sql pivot pivot-table


【解决方案1】:
Select *
from
(
SELECT
    dbo.BuildAPI14(Well.WellID, Construct.SideTrack, Construct.Completion) AS 'API14',
    CAST(ConstructDate.EventDate AS DATE) AS 'First Prod Date',
    Loc.LocType AS 'Location Type',
    CONCAT('Township ',LocExt.Township,LocExt.TownshipDir,' ','Range ',LocExt.Range,LocExt.RangeDir,' Section ',LocExt.Sec,' ',RefCounty.CountyName,' County') AS 'Location' --,
--    tblAPDTracker.SpacingRule AS 'Spacing Rule',
--    Lease.Number AS 'Entity Number',
--    WellHistory.WHComments AS 'Well History Comments'
FROM Well
    LEFT JOIN Construct ON Construct.WellKey = Well.PKey
    LEFT JOIN ConstructReservoir ON ConstructReservoir.ConstructKey = Construct.PKey
    LEFT JOIN Lease ON Lease.Pkey = ConstructReservoir.LeaseKey
    LEFT JOIN WellHistory ON WellHistory.WellKey = Construct.WellKey
    LEFT JOIN tblAPDTracker ON LEFT(tblAPDTracker.APINO,10) = Well.WellID
    LEFT JOIN Loc ON loc.ConstructKey = Construct.PKey AND Loc.LocType IN ('BH','TPI')
    LEFT JOIN LocExt ON LocExt.LocKey = Loc.PKey
    LEFT JOIN ConstructDate ON ConstructDate.ConstructKey = Construct.PKey AND ConstructDate.Event = 'FirstProduction'
    LEFT JOIN RefCounty ON RefCounty.PKey = LocExt.County
WHERE
    WorkType = 'ENTITY' AND
    WellHistory.ModifyUser = 'UTAH\rachelmedina' AND
    YEAR(WellHistory.ModifyDate) = @SearchYear AND
    MONTH(WellHistory.ModifyDate) = @SearchMonth
GROUP BY
    Well.WellID,
    Construct.SideTrack,
    Construct.Completion,
    ConstructDate.EventDate,
    Loc.LocType,
    LocExt.Township,
    LocExt.TownshipDir,
    LocExt.Range,
    LocExt.RangeDir,
    LocExt.Sec,
    RefCounty.CountyName,
    tblAPDTracker.SpacingRule,
    Lease.Number,
    WellHistory.WHComments,
    WellHistory.ModifyDate
    ) p
pivot (min(p.Location) for [Location Type] in ([TPI], [BH])) pvt

透视列中的值需要一个聚合运算符(sum、avg、min、max 等),所以选择一个像 min 或 max 这样的值,它不会尝试对字符串做任何事情,但如果你有它会做一些事情透视列中多次出现(此处的位置)。

我还注释掉了未出现在您的示例结果中的所选列,这可能会影响需要出现在 GROUP BY 子句中的内容。

【讨论】:

  • 成功了,谢谢!
【解决方案2】:

pivot 的另一种选择是使用不同的别名重新连接表,以区分“BH”和“TPI”实例。我还简化了较长的表名,用短别名“w”表示 Well,“wh”表示 wellhouse,等等。

此外,通过查看 A -> B -> C -> D 表的层次结构有助于识别相关组件的位置。然后我将它们复制到下方的位置。

由于查询分别同时连接到 BH 和 TPI,因此我将位置类型删除为列和分组依据。

DECLARE @SearchYear AS VARCHAR(4) = '2021'
DECLARE @SearchMonth AS VARCHAR(2) = '6'

SELECT
        dbo.BuildAPI14(w.WellID, c.SideTrack, c.Completion) API14,
        CAST(cd.EventDate AS DATE) 'First Prod Date',
        CONCAT('Township ', LocExtBH.Township, LocExtBH.TownshipDir,
                ' ','Range ', LocExtBH.Range, LocExtBH.RangeDir,
                ' Section ', LocExtBH.Sec,
                ' ', rcBH.CountyName, ' County') 'BH Location',

        CONCAT('Township ', LocExtTPI.Township, LocExtTPI.TownshipDir,
                ' ','Range ', LocExtTPI.Range, LocExtTPI.RangeDir,
                ' Section ', LocExtTPI.Sec,
                ' ', rcTPI.CountyName, ' County') 'TPI Location',

        ADP.SpacingRule 'Spacing Rule',
        l.Number  'Entity Number',
        wh.WHComments 'Well History Comments'
    FROM 
        Well w
            LEFT JOIN tblAPDTracker ADP
                ON w.WellID = LEFT(trk.APINO,10)
            LEFT JOIN Construct c
                ON w.PKey = c.WellKey
                LEFT JOIN ConstructReservoir cr
                    ON c.PKey = cr.ConstructKey
                    LEFT JOIN Lease l
                        ON cr.LeaseKey = l.Pkey
                LEFT JOIN WellHistory wh
                    ON c.WellKey = wh.WellKey
                LEFT JOIN ConstructDate cd
                    ON c.PKey = cd.ConstructKey 
                    AND cd.Event = 'FirstProduction'

                LEFT JOIN Loc LocBH
                    ON c.PKey = locBH.ConstructKey 
                    AND LocBH.LocType = 'BH'
                    LEFT JOIN LocExt LocExtBH
                        ON LocBH.PKey = LocExtBH.LocKey
                        LEFT JOIN RefCounty rcBH
                            ON LocExtBH.County = rcBH.PKey 

                LEFT JOIN Loc LocTPI
                    ON c.PKey = LocTPI.ConstructKey 
                    AND LocTPI.LocType = 'TPI'
                    LEFT JOIN LocExt LocExtTPI
                        ON LocTPI.PKey = LocExtTPI.LocKey
                        LEFT JOIN RefCounty rcTPI
                            ON LocExtTPI.County = rcTPI.PKey 
    WHERE
            w.WorkType = 'ENTITY' 
        AND wh.ModifyUser = 'UTAH\rachelmedina' 
        AND YEAR(wh.ModifyDate) = @SearchYear 
        AND MONTH(wh.ModifyDate) = @SearchMonth
    GROUP BY
        w.WellID,
        c.SideTrack,
        c.Completion,
        cd.EventDate,
        LocExtBH.Township,
        LocExtBH.TownshipDir,
        LocExtBH.Range,
        LocExtBH.RangeDir,
        LocExtBH.Sec,
        rcBH.CountyName,
        ADP.SpacingRule,
        l.Number,
        wh.WHComments,
        wh.ModifyDate
    ORDER BY
        w.WellId,
        wh.ModifyDate DESC

【讨论】:

  • 谢谢!尽管我没有选择您的答案作为已接受的答案,但我仍然感谢您在答案中所做的工作。我选择了与我最初的 PIVOT 问题最密切相关的答案。不过,我真的很感谢重新格式化和 JOIN 顺序。我总是很乐意处理我的格式并遵循 SQL 格式规则!
  • 在上面的评论中标记您以确保您看到它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-09
  • 2015-10-25
  • 1970-01-01
  • 1970-01-01
  • 2012-12-27
  • 2015-10-19
相关资源
最近更新 更多