【问题标题】:SQL Server : Reuse calculated variable in select clauseSQL Server:在选择子句中重用计算变量
【发布时间】:2016-07-12 08:34:49
【问题描述】:

我的表结构如下:

col1     col2     col3    col4
-------------------------------
aK       Mbcd      ABc    defgh

col2col3col4 列的类型为 varchar(100)col1 的类型为 varchar(500)

我需要一个选择查询来获得如下输出

col1    col2     col3    col4
-------------------------------
aK,Mb   cd,A      Bc,d    efgh

逻辑解释如下:

  1. 结果,Col2、col3 和 col4 最多可以有 4 个字符,但 col1 可以有超过 4 个字符,最多 100 个。

  2. 如果任何一列有更多字符,最后 4 个字符将保留在同一列中,其他额外的列将与前一列的值连接,用逗号 分隔,并且相同的规则将也适用于连接的值。

我编写了以下 T-SQL 语句。它适用于最后两列。但是我想在从 col4 中添加一些字符后,使用 col3 的新计算值去除多余的字符

SELECT
    CASE 
       WHEN X.Col4Length > 4 
          THEN concat(X.col3, ',', substring(x.col4, 0, X.Col4Length - 3))
          ELSE X.col3
    END AS col3,
    CASE 
       WHEN X.Col4Length > 4 
          THEN substring(x.col4, X.Col4Length - 3, x.Col4Length)
          ELSE X.col4
    END AS col4
FROM
    (SELECT
         Col1, Col2, Col3, Col4,
         Len(Col1) AS Col1Length,
         Len(Col2) AS Col2Length,
         Len(Col3) AS Col3Length,
         Len(Col4) AS Col4Length
     FROM       
         mytable) X

【问题讨论】:

  • 您似乎在这里误用了 SQL - 感觉更像是一个演示问题,而不是数据问题,因此在应用程序/报告工具中可能比在 SQL 中更好地处理。此外,明显的边缘情况 - 如果文本总量超过您所说的容量怎么办?例如。输入大小为(100,100,100,100),输出大小为(100,4,4,4)
  • 好的,感谢您指出另一个问题。我将 col1 的大小设置为 500

标签: sql sql-server select


【解决方案1】:

我尝试一个简单的子查询

with t1 as (
select 'aK' col1, 'Mbcd' col2, 'ABc' col3, 'defgh' col4 
---
SELECT LEFT(col, LEN(col) - 12) col1,
      RIGHT(LEFT(col, LEN(col) - 8), 4) col2,
      RIGHT(LEFT(col, LEN(col) - 4), 4) col3,
      RIGHT(col, 4) AS col4
FROM
(
    SELECT col1+','+col2+','+col3+','+col4 AS col
    FROM t1
) t;

【讨论】:

    【解决方案2】:

    您想重用计算变量

    有两种基于集合的 /inline / adhoc 方法(以及更多丑陋的程序):

    • CTEs 提前为整套做这个
    • CROSS APPLY 行级相同

    这样尝试(CTE 方法)

    DECLARE @tbl TABLE(col1 VARCHAR(100),col2 VARCHAR(100),col3 VARCHAR(100),col4 VARCHAR(100));
    INSERT INTO @tbl VALUES
     ('aK','Mbcd','ABc','defgh')
    ,('123456','abc','3456','123456789');
    
    WITH ResolveCol4 AS
    (
        SELECT *
              ,RIGHT(col4,4) AS Col4_resolved
              ,col3 + ',' + CASE WHEN LEN(col4)>4 THEN SUBSTRING(col4,1,LEN(col4)-4) ELSE '' END AS col3_New
        FROM @tbl
    )
    ,ResolveCol3 AS
    (
        SELECT *
              ,RIGHT(col3_New,4) AS Col3_resolved
              ,col2 + ',' + CASE WHEN LEN(col3_New)>4 THEN SUBSTRING(col3_New,1,LEN(col3_New)-4) ELSE '' END AS col2_New
        FROM ResolveCol4 
    )
    ,ResolveCol2 AS
    (
        SELECT *
              ,RIGHT(col2_New,4) AS Col2_resolved
              ,col1 + ',' + CASE WHEN LEN(col2_New)>4 THEN SUBSTRING(col2_New,1,LEN(col2_New)-4) ELSE '' END AS col1_New
        FROM ResolveCol3 
    )
    SELECT col1_new,Col2_resolved,Col3_resolved,Col4_resolved 
    FROM ResolveCol2
    

    结果

    aK,Mb           cd,A    Bc,d    efgh
    123456,abc,34   56,1    2345    6789
    

    【讨论】:

      猜你喜欢
      • 2012-08-05
      • 2020-06-11
      • 1970-01-01
      • 2015-02-27
      • 2016-08-28
      • 2013-06-25
      • 2021-05-22
      • 1970-01-01
      • 2019-06-14
      相关资源
      最近更新 更多