从查找值生成宽表

sru*_*art 5 sql-server query

我有一张宽桌子,看起来像这样:

Table Windspeed
Timestamp           A-004   A-005a  A-006a ... (column 161) E-009
09-Apr-19 00:00:00  13.09   13.95   10.16                   11.71
09-Apr-19 00:05:00  12.17   11.98   12.54                   10.66
Run Code Online (Sandbox Code Playgroud)

我需要以相同的格式生成一个新表,但替换查找表中的列值,如下所示:

Table Powercurve
WindSpeedBin    Power_WdSpd Turb_Num
...
9.5             1216.9      1
10              1362.9      1
10.5            1476.3      1
11              1597        1
11.5            1701.5      1
12              1798.3      1
12.5            1828.5      1
13              1840        1
13.5            1846.1      1
...
9.5             1211.9      2
10              1342.9      2
10.5            1436.3      2
11              1517        2
11.5            1691.5      2
12              1713.3      2
12.5            1801.5      2
13              1833.1      2
13.5            1846.1      2
...
Run Code Online (Sandbox Code Playgroud)

最后,第三个表看起来像这样:

Table NameLookup
TName   Tag     TNum
A-004   A04     1
A-005a  A05     2
A-006a  A06     3
A-008a  A08     4
A-009   A09     5
...
E-009   E09     162
Run Code Online (Sandbox Code Playgroud)

我需要生成一个表,该表采用表 1 (Windspeed) 中的值,查找表 2 (Powercurve) 中的值(四舍五入到最接近的 0.5 以匹配 WindSpeedBin),使用列名查找 Turb_Num 值。任何想法如何解决这个问题?最终结果将如下所示:

Table Expected_Production
Timestamp           A-004   A-005a  A-006a ... (column 161) E-009
09-Apr-19 00:00:00  1840    1846.1  1528.5                  1780.6
09-Apr-19 00:05:00  1828.5  1713.3  1843.9                  1614.5
...
Run Code Online (Sandbox Code Playgroud)

这适用于 Microsoft SQL Server 2017

Jon*_*ite 7

这应该对你有用。至少对于我复制的 PowerCurve 表中的条目,它可以正常工作。这应该让你接近。有关更多详细信息,请参阅代码中的注释。

来自/sf/ask/691179331/ 的帮助,了解如何舍入到最接近的 .5/0。

/** FIRST - we setup the data and tables we need.

    Please note that I didn't copy the entire table of dbo.PowerCurve
    across, so my output is not as complete as yours, but this should
    get you close.
    */

DROP TABLE IF EXISTS dbo.Windspeed 
DROP TABLE IF EXISTS dbo.PowerCurve
DROP TABLE IF EXISTS dbo.NameLookup 

CREATE TABLE dbo.Windspeed 
    (
    [TimeStamp] DATETIME NOT NULL
    , [A-004] DECIMAL(5,2) NOT NULL
    , [A-005a] DECIMAL(5,2) NOT NULL
    , [A-006a] DECIMAL(5,2) NOT NULL
    , [E-009] DECIMAL(5,2) NOT NULL
    )

INSERT INTO dbo.Windspeed 
([TimeStamp], [A-004], [A-005a], [A-006a], [E-009])
VALUES ('4/9/2019 00:00:00', 13.09, 13.95, 10.16, 11.71)
    , ('4/9/2019 00:05:00', 12.17, 11.98, 12.54,10.66)

CREATE TABLE dbo.PowerCurve 
    (
    WindSpeedBIN DECIMAL(5,2) NOT NULL
    , Power_Wdspd DECIMAL(10,2) NOT NULL
    , Turb_Num INT NOT NULL
    )

INSERT INTO dbo.PowerCurve 
(WindSpeedBIN, Power_Wdspd, Turb_Num)
VALUES (13.0, 1840, 1)
    , (13.5, 1846.1, 1)
    , (13.0, 1833.1, 2)
    , (13.5, 1846.1, 2)
    , (12.0, 1798.3, 1)
    , (12.5, 1828.5, 1)
    , (12.0, 1713.3, 2)
    , (12.5, 1801.5, 2)

CREATE TABLE dbo.NameLookup 
    (
    TName VARCHAR(10) NOT NULL
    , Tag VARCHAR(10) NOT NULL
    , TNum INT NOT NULL
    )

INSERT INTO dbo.NameLookup
    (TName, Tag, Tnum)
VALUES ('A-004', 'A04', 1)
    , ('A-005a', 'A05', 2)
    , ('A-006a', 'A06', 3)
    , ('A-008a', 'A08', 4)
    , ('E-009', 'E09', 5)
Run Code Online (Sandbox Code Playgroud)

获取数据

/** GET THE DATA
    - CTE_Source - unpivots so we can get the TNum and PowerCurve
    - CTE_Join - looks up the TNum in dbo.NameLocation and dbo.PowerCurve
    - CTE_Pivot - pivots the data back to make the output what we want
    **/

;WITH CTE_Source AS
    (
    SELECT [TimeStamp]
        , [TName]
        , [Value]
    FROM dbo.Windspeed AS W
        UNPIVOT ([Value] FOR TName IN ([A-004], [A-005a], [A-006a], [E-009])) AS P
    )
, CTE_Join AS
    (
    --NOTE rounding answer from /sf/ask/691179331/
    SELECT S.[TimeStamp]
        , S.[TName]
        , S.[Value]
        , CONVERT(DECIMAL(5,2), ROUND(S.[Value] * 2, 0)/2)  AS RoundedValue
        , NL.TNum
        , PC.Power_Wdspd
    FROM CTE_Source AS S
        LEFT OUTER JOIN dbo.NameLookup AS NL ON NL.TName = S.TName
        LEFT OUTER JOIN dbo.PowerCurve AS PC ON PC.WindSpeedBIN = CONVERT(DECIMAL(5,2), ROUND(S.[Value] * 2, 0)/2) AND PC.Turb_Num = NL.TNum 
    )
, CTE_Pivot AS
    (
    SELECT [TimeStamp]
        , MAX([A-004]) AS [A-004]
        , MAX([A-005a]) AS [A-005a]
        , MAX([A-006a]) AS [A-006a]
        , MAX([E-009]) AS [E-009]
    FROM CTE_Join AS J
        PIVOT (MAX(Power_Wdspd) FOR TName IN ([A-004], [A-005a], [A-006a], [E-009])) AS P
    GROUP BY [TimeStamp]
    )
SELECT * FROM CTE_Pivot 
Run Code Online (Sandbox Code Playgroud)