SQL TOP 1 在子查询中使用时返回 null
Posted
技术标签:
【中文标题】SQL TOP 1 在子查询中使用时返回 null【英文标题】:SQL TOP 1 returning null when used in a sub-query 【发布时间】:2018-06-04 12:06:51 【问题描述】:请您帮忙处理这个子查询 - 它工作正常,我自己为一个客户端运行它,但在添加到查询时返回 null。
对于每个客户,我需要找到订单最多的员工。
这是更大查询的一部分,因此性能也是一个问题。
SELECT c.ClientId, s.BestEmployeeId
FROM client c
LEFT OUTER JOIN(
SELECT TOP 1 o.EmployeeId AS BestEmployeeId, count(o.EmployeeId) AS cnt, o.ClientId
FROM Orders o
WHERE o.EmployeeId > 0
AND o.EmployeeId is not null
GROUP BY o.ClientId, o.EmployeeId
ORDER BY cnt DESC
) AS s on c.ClientId = s.ClientId
【问题讨论】:
用您正在使用的数据库标记您的问题。 【参考方案1】:对于每个客户,我需要找到订单最多的员工。
我会使用聚合和窗口函数来做到这一点:
select oc.*
from (select o.client, o.employeeid, count(*) as cnt,
rank() over (partition by o.client order by count(*) desc) as seqnum
from Orders o
group by o.client, o.employeeid
) oc
where seqnum = 1;
请注意,您似乎不需要client
表,因为orders
似乎同时具有client
和employeeid
。
您的版本正在过滤掉employeeid
的NULL
值。您也可以在子查询中执行此操作(尽管您的问题陈述没有说明这些值)。
【讨论】:
非常感谢 Gordon,但我确实需要客户端表,因为我的主要查询都是关于客户端的 - 正如我所提到的,这只是更大查询的一小部分。 Yogesh 的回答效果很好。 我花了一段时间才弄清楚分区,但这将运行查询所需的时间减半。谢谢戈登。【参考方案2】:你可以使用apply
SELECT c.ClientId, b.BestEmployeeId
FROM client c OUTER APPLY (
SELECT TOP 1 o.EmployeeId AS BestEmployeeId
FROM Orders o
WHERE o.ClientId = c.ClientId AND o.EmployeeId > 0
GROUP BY o.EmployeeId
ORDER BY count(o.EmployeeId) DESC
) b;
【讨论】:
完美,易于理解。谢谢以上是关于SQL TOP 1 在子查询中使用时返回 null的主要内容,如果未能解决你的问题,请参考以下文章