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 似乎同时具有clientemployeeid

您的版本正在过滤掉employeeidNULL 值。您也可以在子查询中执行此操作(尽管您的问题陈述没有说明这些值)。

【讨论】:

非常感谢 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的主要内容,如果未能解决你的问题,请参考以下文章

从父组件调用时,angular 2 变量在子组件方法中返回 null

Oracle中的优化问题

SQL试图在子查询中使用联接表中的列

SQL Server - 在子查询中使用主查询中的列

5. SQL子查询—内嵌的SQL子句

SQL相关子查询和嵌套子查询的区别