如何将 Oracle 转换为 MS SQL Server - PIVOT 和 STRING_AGG

问题描述 投票:0回答:1

请帮我将 Oracle 转换为 SQL Server PIVOT。

table_cases 包含以下数据:

预期结果如下。注意:我只是将“hour-01”的“hour-Nth”列快捷到“hour-24”列。

甲骨文:

SELECT 
  "column_user_id", 
  "column_user_name", 
  "column_cases", 
  "column_number_hour", 
  "column_number_index"
FROM 
  table_cases 
  /* Use Pivot to flip the time windows */
  PIVOT (
    listagg(column_cases, ',') within group(
      order by 
        column_number_hour
    ) for column_number_index in (
      0 as "Hour-01", 1 as "Hour-02", 2 as "Hour-03", 
      3 as "Hour-04", 4 as "Hour-05", 5 as "Hour-06", 
      6 as "Hour-07", 7 as "Hour-08", 8 as "Hour-09", 
      9 as "Hour-10", 10 as "Hour-11", 11 as "Hour-12", 
      12 as "Hour-13", 13 as "Hour-14", 14 as "Hour-15", 
      15 as "Hour-16", 16 as "Hour-17", 17 as "Hour-18", 
      18 as "Hour-19", 19 as "Hour-20", 20 as "Hour-21", 
      21 as "Hour-22", 22 as "Hour-23", 23 as "Hour-24"
    )
  )

当我尝试像这样将其转换为 SQL Server 时。仅当有助于理解我的问题时,我才为此示例制作了一个临时表。

CREATE TABLE #table_cases (
    column_user_id nvarchar(10),
    column_user_name nvarchar(50),
    column_cases int,
    column_number_hour int,
    column_index_hour int
)

INSERT INTO #table_cases (column_user_id, column_user_name, column_cases, column_number_hour, column_index_hour)
VALUES ('AAA111', 'Shelby, Marie', 5, 9, 0); 

INSERT INTO #table_cases (column_user_id, column_user_name, column_cases, column_number_hour, column_index_hour)
VALUES ('BBB222', 'Wayne, Johnny', 15, 10, 1); 

INSERT INTO #table_cases (column_user_id, column_user_name, column_cases, column_number_hour, column_index_hour)
VALUES ('BBB222', 'Wayne, Johnny', 51, 9, 0); 

SELECT * 
FROM 
    (SELECT 
         "column_user_id", 
         "column_user_name", 
         "column_cases", 
         "column_number_hour", 
         "column_number_index"
     FROM 
         #table_cases) AS TABLE_1
  /* Use Pivot to flip the time windows */
 PIVOT (
    STRING_AGG( TABLE_1."column_cases", ';') WITHIN GROUP (ORDER BY TABLE_1."column_number_hour")  
    for TABLE_1.column_number_index in (
      0 as "Hour-01", 1 as "Hour-02", 2 as "Hour-03", 
      3 as "Hour-04", 4 as "Hour-05", 5 as "Hour-06", 
      6 as "Hour-07", 7 as "Hour-08", 8 as "Hour-09", 
      9 as "Hour-10", 10 as "Hour-11", 11 as "Hour-12", 
      12 as "Hour-13", 13 as "Hour-14", 14 as "Hour-15", 
      15 as "Hour-16", 16 as "Hour-17", 17 as "Hour-18", 
      18 as "Hour-19", 19 as "Hour-20", 20 as "Hour-21", 
      21 as "Hour-22", 22 as "Hour-23", 23 as "Hour-24" 
    )
  ) AS PIVOT_TABLE_1

我收到以下错误:

错误:“;”附近的语法不正确

ORDER BY
行上的
ORDER BY TABLE_1."column_number_hour"
也显示错误。

行上的“0” ->

0 as "Hour-01"
也会引发错误。

在 Oracle 中,函数“listagg”在

PIVOT
函数中运行良好。但是在 SQL Server 中,我们可以在
STRING_AGG
中使用
PIVOT
作为聚合函数吗?

因为它似乎出错了。将别名放在column_number_index“in”中的意图也显示错误,这可能吗?

sql-server oracle pivot-table database-migration string-agg
1个回答
0
投票

你很接近。我看到的两个问题是 (1) SQL Server

PIVOT
不支持
STRING_AGG()
函数,(2) SQL Server 不允许对
FOR
PIVOT
子句中的值直接使用别名。

第一个问题可以通过分别执行

GROUP BY
STRING_AGG()
然后将其输入到
PIVOT
来解决。第二个问题可以通过在最终选择中为
PIVOT
列添加别名来解决。

类似:

SELECT
    column_user_id, 
    column_user_name,
    [0] as "Hour-01",  [1] as "Hour-02",  [2] as "Hour-03", 
    [3] as "Hour-04",  [4] as "Hour-05",  [5] as "Hour-06", 
    [6] as "Hour-07",  [7] as "Hour-08",  [8] as "Hour-09", 
    [9] as "Hour-10",  [10] as "Hour-11", [11] as "Hour-12", 
    [12] as "Hour-13", [13] as "Hour-14", [14] as "Hour-15", 
    [15] as "Hour-16", [16] as "Hour-17", [17] as "Hour-18", 
    [18] as "Hour-19", [19] as "Hour-20", [20] as "Hour-21", 
    [21] as "Hour-22", [22] as "Hour-23", [23] as "Hour-24" 
FROM (
    SELECT
        TABLE_1.column_user_id, 
        TABLE_1.column_user_name,
        TABLE_1.column_number_index,
        STRING_AGG(TABLE_1.column_cases, ';')
            WITHIN GROUP (ORDER BY TABLE_1.column_number_hour)
            AS aggregated_cases
    FROM (
        SELECT 
            column_user_id, 
            column_user_name, 
            column_cases, 
            column_number_hour, 
            column_number_index
        FROM table_cases
    ) AS TABLE_1
    GROUP BY column_user_id, column_user_name, column_number_index
) G
PIVOT (
    MAX(G.aggregated_cases)  
    FOR G.column_number_index IN (
        [0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11],
        [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23]
    )
) AS PIVOT_TABLE_1

带有一些虚构数据的示例结果:

列_用户_id 列_用户名 小时-01 小时-02 ... 24 点
1 用户1 红;蓝 黄;绿 ...
2 用户2 ... 青色;洋红色;黄色;黑色

请参阅 this db<>fiddle 以获取工作示例。

(旁注:检查您对

column_number_index
column_number_hour
的用法。当前的用法对我来说似乎很奇怪。)

© www.soinside.com 2019 - 2024. All rights reserved.