【问题标题】:Using a variable in a view creation script in SQL Server在 SQL Server 的视图创建脚本中使用变量
【发布时间】:2020-10-15 06:27:26
【问题描述】:

我现在在 SQL Server 中有一个中间视图,还有一个最终视图,如下:

中间视图:

SELECT
    ....
    ElapsedDays = DATEDIFF(d, ri.DateReceived, GETDATE()),
    .....
FROM 
    RegionalInventory AS ri

最终视图:

SELECT
    ....
    PenaltyBucket = COALESCE(CASE WHEN inv.ElapsedDays <= 30 THEN 'Not Late' END,
                             CASE WHEN inv.ElapsedDays > 30 THEN 'Late' END)
    ....
FROM 
    Inventory AS inv

我想知道是否有办法将两个视图合并为一个,但我不确定如何声明一个变量来保存ElapsedDays 的值,然后用它来设置@987654324 的值@ 列并进行逻辑测试,创建PenaltyBucket 列并用正确的值填充它。

【问题讨论】:

    标签: sql sql-server tsql select sql-view


    【解决方案1】:

    您可以将内部视图定义为 CTE,然后再次引用它。

    创建视图 [模式名称。 ] view_name [ ( column_name [ ,...n ] ) ] AS [;] ::=
    [ WITH [ ,...n ] ]
    选择

    以下是演示代码供您参考。

    create view vw_test
    as 
    WITH cte_1 as
    (
    select 1 as a
    )
    SELECT t.testname
    from (values (1,'test1'),(2,'test2')) as t(a,testname)
    join cte_1 as c
    on c.a = t.a
    
    select * from vw_test
    

    你能做的是。示例代码供您参考。

    CREATE VIEW outerView
    AS
    WITH cte_innerview
    as
    (
    SELECT
        ....
        ElapsedDays = DATEDIFF(d, ri.DateReceived, GETDATE()),
        .....
    FROM 
        RegionalInventory AS ri
    )
    SELECT
        ....
        PenaltyBucket = COALESCE(CASE WHEN inv.ElapsedDays <= 30 THEN 'Not Late' END,
                                 CASE WHEN inv.ElapsedDays > 30 THEN 'Late' END)
        ....
    FROM 
        Inventory AS inv
    INNER JOIN cte_innerview as c
    on c.InventoryId = inv.InventoryId
    

    【讨论】:

      【解决方案2】:

      假设你真的只有一个表(称为RegionalInventory,这是横向连接的方便位置:

      SELECT . . ., v.ElapsedDays,
             (CASE WHEN v.ElapsedDays <= 30 THEN 'Not Late'
                   WHEN v.ElapsedDays > 30 THEN 'Late'
              END) as PenaltyBucket
      FROM RegionalInventory ri CROSS APPLY
           (VALUES (DATEDIFF(day, ri.DateReceived, GETDATE()))
           ) v(ElapsedDays);
      

      注意:

      • 没有必要将COALESCE() 与两个CASE 表达式一起使用。一个CASE 可以处理多种情况。
      • 在使用DATEDIFF() 时拼出day。这只是一个好习惯(考虑一下:m 是指几分钟还是几个月?)

      【讨论】:

      • 我实际上有两个以上的 CASE 表达式,但为简洁起见,这里只列出了两个,我只处理一个表。我直到测试出来
      • @coyotepoint 。 . . values 子句可以定义多个列:(values ( . . . , . . . , . . .)) v(a, b, c).
      【解决方案3】:

      你可以重复SELECT子句中的表达式:

      SELECT
          ...,
          DATEDIFF(d, ri.DateReceived, GETDATE()) AS ElapsedDays,
          CASE 
              WHEN DATEDIFF(d, ri.DateReceived, GETDATE()) <= 30 then 'Not Late'
              ELSE 'Late' 
          END AS PenaltyBucket 
          ...
      FROM RegionalInventory as ri
      

      或者,您可以使用子查询:

      SELECT
          t.*,
          CASE 
              WHEN ElapsedDays  <= 30 then 'Not Late'
              ELSE 'Late' 
          END AS PenaltyBucket 
      FROM (
          SELECT
              ...,
              DATEDIFF(d, ri.DateReceived, GETDATE()) AS ElapsedDays,
              ...
          FROM RegionalInventory as ri
      ) t
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-11-28
        • 2013-09-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-15
        相关资源
        最近更新 更多