创建 returns table 在 SQL 中的函数

Create function that returns table in SQL

我想用一些逻辑创建视图,比如使用(for 循环,if .. else),但因为 SQL 不支持 我想创建 table 不带参数的函数并且 return 是 table.

我有 orders 的 table 如下

OrderId  Destination  Category  Customer
----------------------------------------
6001     UK           5         Adam
6002     GER          3         Jack

和 table 对于 tracking orders 如下

ID  OrderID  TrackingID
-----------------------
1   6001     1
2   6001     2
3   6002     2

这里是 types of tracking

ID  Name
--------------
1   Processing
2   Shipped
3   Delivered

正如您在tracking order中看到的,订单号可能有多个记录,具体取决于发生的跟踪事件的数量。

我们有超过 25 种跟踪类型,但我没有在此处列出。这意味着一个订单可以在 tracking order table.

中存在 25 次

话虽如此,我的要求是创建如下视图,条件是订单必须属于 5 或​​ 3 个类别(我们有超过 15 个类别)。

并且每当我 运行 函数时,它必须 return 更新信息。

因此,例如,当发生新跟踪并将其插入 tracking order 时,我想 运行 我的函数并在相应的标志列中查看更新(例如 isDelivered) .

我真的很困惑实现这一目标的最佳方法是什么。我不需要确切的脚本,我只需要了解实现它的方法,因为我对 SQL

不是很熟悉

这可以通过使用条件聚合的交叉表查询来完成。像这样

select o.OrderID, 
       max(case when tt.[Name]='Processing' then 1 else 0 end) isPrepared,
       max(case when tt.[Name]='Shipped' then 1 else 0 end) isShipped,
       max(case when tt.[Name]='Delivered' then 1 else 0 end) isDelivered
from orders o
     join tracking_orders tro on o.OrderID=tro.OrderID
     join tracking_types tt on tro.TrackingID=tt.TrackingID
where o.category in(3, 5)
group by o.OrderID;

[编辑] 为了细分类别 3 订单,向交叉表添加了 3 个额外的列。

select o.OrderID, 
       max(case when tt.[Name]='Processing' then 1 else 0 end) isPrepared,
       max(case when tt.[Name]='Shipped' then 1 else 0 end) isShipped,
       max(case when tt.[Name]='Delivered' then 1 else 0 end) isDelivered,
       max(case when tt.[Name]='Processing' and o.category=3 then 1 else 0 end) isC3Prepared,
       max(case when tt.[Name]='Shipped' and o.category=3 then 1 else 0 end) isC3Shipped,
       max(case when tt.[Name]='Delivered'  and o.category=3 then 1 else 0 end) isC3Delivered
from orders o
     join tracking_orders tro on o.OrderID=tro.OrderID
     join tracking_types tt on tro.TrackingID=tt.TrackingID
where o.category in(3, 5)
group by o.OrderID;