Sql 确定另一个联接表中是否存在单行的最快方法,相当于任何linq函数

Sql 确定另一个联接表中是否存在单行的最快方法,相当于任何linq函数,sql,sql-server,Sql,Sql Server,我试图为另一个表上的联接返回一个位字段,但如果存在一条记录,则返回“1”,如果不存在,则返回“0”。我负担不起放慢运营速度,因此它需要成为最有效的解决方案。我试图在select语句中的HasRecord行上实现这一点-这目前不起作用 SELECT AVG(CS.HourMinutes00) AS HourMinutes00, AVG(CS.HourMinutes01) AS HourMinutes01, AVG(CS.HourMinutes02) AS HourMinu

我试图为另一个表上的联接返回一个位字段,但如果存在一条记录,则返回“1”,如果不存在,则返回“0”。我负担不起放慢运营速度,因此它需要成为最有效的解决方案。我试图在select语句中的HasRecord行上实现这一点-这目前不起作用

SELECT 
    AVG(CS.HourMinutes00) AS HourMinutes00,
    AVG(CS.HourMinutes01) AS HourMinutes01,
    AVG(CS.HourMinutes02) AS HourMinutes02,
    AVG(CS.HourMinutes03) AS HourMinutes03,
    AVG(CS.HourMinutes04) AS HourMinutes04,
    AVG(CS.HourMinutes05) AS HourMinutes05,
    AVG(CS.HourMinutes06) AS HourMinutes06,
    AVG(CS.HourMinutes07) AS HourMinutes07,
    AVG(CS.HourMinutes08) AS HourMinutes08,
    AVG(CS.HourMinutes09) AS HourMinutes09,
    AVG(CS.HourMinutes10) AS HourMinutes10,
    AVG(CS.HourMinutes11) AS HourMinutes11,
    AVG(CS.HourMinutes12) AS HourMinutes12,
    AVG(CS.HourMinutes13) AS HourMinutes13,
    AVG(CS.HourMinutes14) AS HourMinutes14,
    AVG(CS.HourMinutes15) AS HourMinutes15,
    AVG(CS.HourMinutes16) AS HourMinutes16,
    AVG(CS.HourMinutes17) AS HourMinutes17,
    AVG(CS.HourMinutes18) AS HourMinutes18,
    AVG(CS.HourMinutes19) AS HourMinutes19,
    AVG(CS.HourMinutes20) AS HourMinutes20,
    AVG(CS.HourMinutes21) AS HourMinutes21,
    AVG(CS.HourMinutes22) AS HourMinutes22,
    AVG(CS.HourMinutes23) AS HourMinutes23,
    CASE WHEN EXISTS (SELECT TOP 1 * FROM LocationHistory LH JOIN MachineActivity MA ON LH.MachineActivityId = MA.Id JOIN Machine M ON MA.MachineId = M.Id WHERE CS.ActivityDate = MA.ActivityDate AND CS.MachineId = M.Id) THEN CAST (1 AS BIT) ELSE CAST (0 AS BIT) END AS HasRecord
FROM 
    CustomerSummary
WHERE
    ActivityDate >= '2021-02-15'
AND
    ActivityDate <= '2021-02-21'
AND 
    CS.MachineNumber = '1'
AND
    CS.SiteId = '1'
GO

带有聚合的子查询通常很棘手。您可以通过使用APPLY将逻辑移动到FROM子句来修复语法问题:

这应该是有效的

注:

除非你真的知道自己在做什么,否则不要使用NOLOCK。大多数用户不希望在结果中使用不一致的数据。 存在时不需要选择顶部。
请解释什么不起作用。真正的问题看起来像是你有一个大规模的非规范化表。还有,你真的需要那个锁吗?您确实了解它的功能,对吗?为了清晰起见,删除了nolock,就像在测试中一样。在非规范化方面是正确的,但必须处理给定的内容。不起作用-抛出一个可以理解的错误,因为它不是显示当前方法的正确解决方案。您不需要帮助查询优化器。它知道,只要在EXISTS测试中找到一行,它就可以返回一个真实结果。感谢Gordan,该解决方案可以工作,但会额外增加6秒的查询执行时间,这可能是它加入的庞大数据集。。。如果我找不到更快的解决方案,可能需要重新考虑这个问题。在CustomerSummaryMachineEnumber上的索引ActivityDate可能会有所帮助。
SELECT . . .,
       v.HasRecord
FROM  CustomerSummary CS CROSS APPLY
      (VALUES (CASE WHEN EXISTS (SELECT 1
                                 FROM LocationHistory LH JOIN 
                                      MachineActivity MA
                                      ON LH.MachineActivityId = MA.Id JOIN
                                      Machine M
                                      ON MA.MachineId = M.Id
                                 WHERE CS.ActivityDate = MA.ActivityDate AND
                                       CS.MachineId = M.Id
                               )
                    THEN CAST (1 AS BIT)
                    ELSE CAST (0 AS BIT)
               END)
      ) v(HasRecord)
WHERE . . .
GROUP BY v.HasRecord;