用于选择生成列的tsql别名

问题描述:

在T-SQL中,我需要为计算值分配一个别名,以便在CASE子句中使用它。用于选择生成列的tsql别名

SELECT 
    RUT, 
    (11 - ((SUBSTRING(RUT, 1, 1) * 3 
      + SUBSTRING(RUT, 2, 1) * 2 
      + SUBSTRING(RUT, 3, 1) * 7 
      + SUBSTRING(RUT, 4, 1) * 6 
      + SUBSTRING(RUT, 5, 1) * 5 
      + SUBSTRING(RUT, 6, 1) * 4 
      + SUBSTRING(RUT, 7, 1) * 3 
      + SUBSTRING(RUT, 8, 1) * 2) % 11)) AS VerifDigit, 
    CASE 
     WHEN VerifDigit = 10 THEN 'K' 
     WHEN VerifDigit = 11 THEN '0' 
     ELSE VerifDigit 
    END 
FROM 
    Citizen 

您也可以使用CROSS APPLY和VALUES来计算结果,然后在您的CASE语句中引用该值,例如...

SELECT 
    RUT, 
    xa.VerifDigit, 
    CASE 
     WHEN xa.VerifDigit = '10' THEN 'K' 
     WHEN xa.VerifDigit = '11' THEN '0' -- this will never occur 
     ELSE xa.VerifDigit 
    END 
FROM 
    Citizen 
CROSS APPLY (VALUES(cast((11 - ((substring(RUT, 1, 1) * 3 
          + SUBSTRING(RUT, 2, 1) * 2 
          + SUBSTRING(RUT, 3, 1) * 7 
          + SUBSTRING(RUT, 4, 1) * 6 
          + SUBSTRING(RUT, 5, 1) * 5 
          + SUBSTRING(RUT, 6, 1) * 4 
          + SUBSTRING(RUT, 7, 1) * 3 
          + SUBSTRING(RUT, 8, 1) * 2) % 11)) 
        AS char(2)))) xa(VerifDigit) 

几件事情值得指出的是,虽然...

  1. 您需要的结果(VerifDigit)转换为字符数据类型,如果你是“K”代替它否则CASE将失败并进行数据转换;这在示例中显示。
  2. Modulo(%)11的结果永远不会是11;任何除以11的余数都将介于0和10之间,因此第二个CASE/WHEN将会从开始不会出现

您不能在定义它的select子句中使用别名。一种解决方法是子查询,例如

WITH cte AS (
    SELECT 
     RUT,(11 - ((SUBSTRING(RUT,1,1)*3 
     + SUBSTRING(RUT,2,1)*2 
     + SUBSTRING(RUT,3,1)*7 
     + SUBSTRING(RUT,4,1)*6 
     + SUBSTRING(RUT,5,1)*5 
     + SUBSTRING(RUT,6,1)*4 
     + SUBSTRING(RUT,7,1)*3 
     + SUBSTRING(RUT,8,1)*2)%11)) AS VerifDigit 
    FROM Citizen 
) 

SELECT 
    VerifDigit, 
    CASE 
     WHEN VerifDigit = 10 THEN 'K' 
     WHEN VerifDigit = 11 THEN '0' 
     ELSE VerifDigit 
    END 
FROM cte;