我正在构建一个由 SQL 后端和多个与该后端通信的微服务组成的应用程序。我试图通过网络从数据库获取尽可能少的数据,因此我试图获取准确的记录,这样我就不必开始在应用程序逻辑中循环。
所以这是源表:
订单ID | 主题 | 层级级别 | 负责人 | 状态 |
---|---|---|---|---|
1234 | A | 0 | 杰森 | 打开 |
1234 | A | 0 | 卡罗尔 | 打开 |
1234 | A | 1 | 杰夫 | 打开 |
1234 | A | 2 | 阿丽娜 | 打开 |
1234 | A | 3 | 艾琳 | 打开 |
1234 | B | 0 | 约翰 | 已关闭 |
1234 | B | 1 | 丹尼 | 打开 |
1234 | B | 1 | 席琳 | 打开 |
1234 | B | 2 | 科里 | 打开 |
1234 | B | 3 | 洛根 | 打开 |
1234 | C | 0 | 杰森 | 已关闭 |
1234 | C | 1 | 阿妮莎 | 打开 |
1234 | C | 2 | 塞德里克 | 打开 |
1234 | D | 0 | 彼得 | 已关闭 |
1234 | D | 1 | 乔安娜 | 已关闭 |
1234 | D | 2 | 弗里克 | 打开 |
1234 | E | 0 | 卡罗尔 | 已关闭 |
1234 | E | 1 | 辛西娅 | 已关闭 |
1234 | E | 2 | 迪德拉 | 打开 |
基于“orderID”作为查询的输入参数,我应该为每个主题获取队列中的下一个人员,因此该主题的 HierarchyLevel 编号最低,状态为“Open”。所以每个主题都可以返回多次,只要返回的记录在“HierarchyLevel”中具有尽可能低的值并且状态为“Open”即可。
所以我希望这是存储过程的输出:
订单ID | 主题 | 层级级别 | 负责人 | 状态 |
---|---|---|---|---|
1234 | A | 0 | 杰森 | 打开 |
1234 | A | 0 | 卡罗尔 | 打开 |
1234 | B | 1 | 丹尼 | 打开 |
1234 | B | 1 | 席琳 | 打开 |
1234 | C | 1 | 阿妮莎 | 打开 |
1234 | D | 2 | 弗里克 | 打开 |
1234 | E | 2 | 迪德拉 | 打开 |
我尝试使用 min() 但没有成功:
我尝试过的一些事情:
select * from mytable as a
inner join (
select Topic, min(HierarchyLevel) as min_value
from mytable
group by Topic
) t on t.Topic = a.Topic and a.HierarchyLevel = min_value and a.OrderID = @OrderID and Status = 'Open'
select * from mytable as a
inner join (
select Topic, Status ,min(HierarchyLevel) as min_value
from mytable
group by Topic , Status HAVING Status = 'Open'
) t on t.Topic = a.Topic and a.HierarchyLevel = min_value and a.OrderID = @OrderID and a.Status = 'Open'
没有一个达到预期的结果。有人能引导我走向正确的方向吗?
非常感谢。
查找 RANK() OVER (...)。我猜想是这样的:
SELECT OrderID, Topic, hierarchyLevel, Responsible_Person, Status
FROM (
SELECT OrderID, Topic, hierarchyLevel, Responsible_Person, Status
, RANK() OVER (PARTITION BY OrderID, Topic
ORDER BY hierarchyLevel) AS rnk
FROM t
WHERE Status = 'Open'
) AS T
WHERE rnk = 1;
一个直接的解决方案是使用 exists:
来使用相关聚合select *
from t
where exists (
select * from t t2
where t2.OrderId = t.OrderId
and t2.Topic = t.Topic
and t2.Status = 'Open'
group by t2.OrdeRId, t2.Topic
having Min(t2.hierarchyLevel) = t.hierarchyLevel
);
演示数据库<>小提琴
结果:
一种方法是检查所有处于打开状态的记录
intersect
,其中所述记录也具有每个 order_id 和 topic 的最低 heirarchy_level
select order_id, topic, heirarchy_level, responsible_person, status
from t
where status='Open'
intersect
select order_id, topic, min(heirarchy_level) over (partition by order_id, topic), responsible_person, status
from t
where status='Open'