【问题标题】:Oracle SQL to T-SQL conversion with NVL2 function to Case Statement使用 NVL2 函数将 Oracle SQL 转换为 T-SQL 到 Case 语句
【发布时间】:2018-11-12 00:06:18
【问题描述】:

目前正在进行 Oracle 到 T-SQL 语句的转换。这是我要转换的内容:

SELECT USC.USER_ID
  ,NVL2 (MAX(STREET_1), MAX(STREET_1) || CHR (10), '')
|| NVL2 (MAX(STREET_2), MAX(STREET_2) || CHR (10), '')
|| NVL2 (MAX(STREET_3), MAX(STREET_3) || CHR (10), '')
|| NVL2 (MAX(STREET_4), MAX(STREET_4) || CHR (10), '') AS STREETS
  ,MAX(ADDR.CITY) AS CITY
  ,MAX(ADDR.POSTAL_CODE) AS POSTAL_CODE
  ,MAX(ADDR.STATE_ID) AS STATE_ID
  ,MAX(ADDR.COUNTRY_ID) AS COUNTRY_ID
FROM ES_W_USER_CONT_INF USC
LEFT JOIN DW_ERSDB_LDSJOBS_ADDRESS ADDR ON (USC.ADDRESS_ID = 
ADDR.ADDRESS_ID)
GROUP BY USC.USER_ID

我最好的尝试。我意识到这很遥远,但我没有太多编写案例陈述的经验:

SELECT USC.USER_ID
,CASE 
 WHEN ADDR.STREET_1 IS NOT NULL THEN ADDR.STREET_1 || CHAR (10) 
 WHEN ADDR.STREET_1 IS NULL THEN '' 
 WHEN ADDR.STREET_2 IS NOT NULL THEN ADDR.STREET_2 || CHAR (10) 
 WHEN ADDR.STREET_2 IS NULL THEN '' 
 WHEN ADDR.STREET_3 IS NOT NULL THEN ADDR.STREET_3 || CHAR (10) 
 WHEN ADDR.STREET_3 IS NULL THEN '' 
 WHEN ADDR.STREET_4 IS NOT NULL THEN ADDR.STREET_4 || CHAR (10) 
 WHEN ADDR.STREET_4 IS NULL THEN '' 
 END
,MAX(ADDR.CITY) AS CITY
,MAX(ADDR.POSTAL_CODE) AS POSTAL_CODE
,MAX(ADDR.STATE_ID) AS STATE_ID
,MAX(ADDR.COUNTRY_ID) AS COUNTRY_ID
FROM DSS_ERS_STAGE.ES_W_USER_CONT_INF USC
LEFT JOIN DSS_ERS_STAGE.ES_W_ADDRESS ADDR ON (USC.ADDRESS_ID = 
ADDR.ADDRESS_ID)
GROUP BY USC.USER_ID

【问题讨论】:

  • 我很困惑。这两个查询看起来一样,而且看起来都可以在 Oracle 和 SQL Server 中正常工作。我也没有看到 NVL2() 的任何用法
  • 我的错误。固定。

标签: sql sql-server tsql case nvl


【解决方案1】:

你应该可以将 NVL2 换成 COALESCE

SELECT USC.USER_ID
  ,COALESCE((MAX(STREET_1) + CHAR (10), '')
 + COALESCE(MAX(STREET_2) + CHAR (10), '')
 + COALESCE(MAX(STREET_3) + CHAR (10), '')
 + COALESCE(MAX(STREET_4) + CHAR (10), '') AS STREETS
  ,MAX(ADDR.CITY) AS CITY
  ,MAX(ADDR.POSTAL_CODE) AS POSTAL_CODE
  ,MAX(ADDR.STATE_ID) AS STATE_ID
  ,MAX(ADDR.COUNTRY_ID) AS COUNTRY_ID
FROM DSS_ERS_STAGE.ES_W_USER_CONT_INF USC
LEFT JOIN DW_ERSDB_LDSJOBS_ADDRESS ADDR ON (USC.ADDRESS_ID = 
ADDR.ADDRESS_ID)
GROUP BY USC.USER_ID

您可能必须连接 MAX(CHAR(10)) 我不确定。这不是功能问题,只是使用 GROUP BY 的语法。

【讨论】:

    【解决方案2】:

    您仍然有一些 Oracle 特定的项目,并且缺少一些有用的 SQL Server 功能。这是我的转换尝试:

     SELECT USC.USER_ID,
       COALESCE(ADDR.STREET_1 + CHAR (10), '') +
       COALESCE(ADDR.STREET_2 + CHAR (10), '') +
       COALESCE(ADDR.STREET_3 + CHAR (10), '') +
       COALESCE(ADDR.STREET_4 + CHAR (10), '') AS Streets,
      ,MAX(ADDR.CITY) AS CITY
      ,MAX(ADDR.POSTAL_CODE) AS POSTAL_CODE
      ,MAX(ADDR.STATE_ID) AS STATE_ID
      ,MAX(ADDR.COUNTRY_ID) AS COUNTRY_ID
    FROM DSS_ERS_STAGE..ES_W_USER_CONT_INF USC
    LEFT JOIN DSS_ERS_STAGE..ES_W_ADDRESS ADDR 
      ON USC.ADDRESS_ID = ADDR.ADDRESS_ID
    GROUP BY USC.USER_ID
    

    具体项目:COALESCE() 接受参数列表并返回第一个非空值。如果任何 ADDR.STREET_x 字段为空,则该字段和 CHAR(10) 的连接也将为空(除非您更改 ANSI_NULL 默认值)。

    表名中的双点:我假设 DSS_ERS_STAGE 是数据库名称。如果在 SQL Server 中使用 Database Name.Table Name,则需要指定第三级 - 架构名称。在这种情况下,我假设默认模式名称 (dbo) 可以省略,但应包含分隔符。如果您使用不同的架构,例如“db2data”,您的表引用将如下所示:

    FROM DSS_ERS_STAGE.db2data.ES_W_USER_CONT_INF USC
    

    希望对你有所帮助。

    【讨论】:

    • 就是这样!谢谢你。我在 group by 中添加了几列,效果很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-24
    • 2017-01-15
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    相关资源
    最近更新 更多