在 SQL 服务器的视图创建脚本中使用变量

Using a variable in a view creation script in SQL Server

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

中间视图:

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 的值,然后用它来设置值对于 ElapsedDays 列并进行逻辑测试,创建 PenaltyBucket 列并用正确的值填充它。

您可以只重复 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

假设你真的只有一个table(叫做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 是分钟还是月?)

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

CREATE VIEW [ schema_name . ] view_name [ ( column_name [ ,...n ] ) ] AS <select_statement> [;] <select_statement> ::=
[ WITH <common_table_expression> [ ,...n ] ]
SELECT <select_criteria>

下面是演示代码,供您参考。

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