Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 在这个查询中,除了左连接,我还有什么选择?_Sql Server_Join_Reporting Services - Fatal编程技术网

Sql server 在这个查询中,除了左连接,我还有什么选择?

Sql server 在这个查询中,除了左连接,我还有什么选择?,sql-server,join,reporting-services,Sql Server,Join,Reporting Services,我在其他人创建的SSRS报告中使用了这个查询。左连接是问题的原因。如果我将其更改为内部联接,我将在大约15秒内得到不正确的结果。使用左连接,我在20分钟后取消了查询。我在预算、专业人员和交易中都添加了一个索引,专业人员的绩效没有变化。有没有办法重写查询而不使用左连接 SELECT profs.ProfName as orig ,profs.Initials ,DATEPART(year, TransDate) as [Year] ,SUM(CASE WHEN IsFlatFee = 'Y'

我在其他人创建的SSRS报告中使用了这个查询。左连接是问题的原因。如果我将其更改为内部联接,我将在大约15秒内得到不正确的结果。使用左连接,我在20分钟后取消了查询。我在预算、专业人员和交易中都添加了一个索引,专业人员的绩效没有变化。有没有办法重写查询而不使用左连接

SELECT 
profs.ProfName as orig
,profs.Initials
,DATEPART(year, TransDate) as [Year]
,SUM(CASE WHEN IsFlatFee = 'Y'  OR COALESCE(MT.Admin, 'N') = 'Y' 
    THEN 0.0
    ELSE Units * (aph.assignedpercent/100) * isnull(B.rate, 0.0)
    END) AS ctp
,SUM(CASE WHEN IsFlatFee = 'Y'  OR COALESCE(MT.Admin, 'N') = 'Y' 
    THEN 0
    ELSE Units
    END * (aph.assignedpercent/100)) AS worked_hours
,SUM(Value * (aph.assignedpercent/100)) AS worked_value
, 0 AS billed_hours
,0 AS billed_value
,0 AS billed_netamt
, 0.0 as paid
, 0.0 as wo
FROM Transactions Trans 
INNER JOIN Matters Matts ON Trans.matters  = Matts.matters 
INNER JOIN MatterTypes MT ON Matts.mattertype  = MT.mattertypesdesc
and MT.Admin <> 'Y'
INNER JOIN Components Comps ON Comps.components  = Trans.components 
and Comps.CompType = 'F'
INNER JOIN AssignedProfsHistory APH on APH.Matters = Trans.Matters
and APH.AssignedType = 'Originating'
and Trans.TransDate between APH.EffectiveDate and 
ISNULL(EndDate,'12/31/2099')
INNER JOIN  Professionals profs on profs.Professionals  = APH.Professionals 
    and profs.ProfType = 'Member'
    and profs.IsActive = 'Y'
    and profs.IsBillable = 'Y'
**LEFT join** (SELECT Budgets.Professionals as timekeeper, Budgets.Amount as 
rate, Budgets.PeriodDate
FROM Matters Matts
INNER JOIN Budgets ON Matts.matters  = Budgets.matters 
    and cast(Budgets.PeriodDate as Date) <= '2017-12-31'
    AND MONTH('2017-12-31') = MONTH(Budgets.PeriodDate)
WHERE Matts.MatterID  = '99999-99.003') as B 
    *on B.timekeeper = Trans.Professionals*
    and YEAR(B.PeriodDate) = DATEPART(year, TransDate)
WHERE cast(transdate as DATE) between dateadd(day, 1, DATEADD(year, -3, 
'2017-12-31')) and '2017-12-31'
GROUP BY profs.ProfName, profs.Initials, DATEPART(year, TransDate)

正如肖恩和亚伦所说。有太多潜在的问题

你似乎是我从列名猜到你加入了mattertypesdesc文本列。事实上,大部分工作都是针对文本列进行的。甚至Matts.MatterID也是文本。这在您的场景中可能不可能实现,但如果表具有整数主键,并且您在这些主键上进行连接,则性能会更好

不管怎么说,猜猜看。。。。如果用临时表替换左侧联接中的子查询,您可能会很快获得成功

所以,在您执行现有查询之前

SELECT Budgets.Professionals as timekeeper, Budgets.Amount as rate, Budgets.PeriodDate
INTO #t
FROM Matters Matts
INNER JOIN Budgets ON Matts.matters  = Budgets.matters 
    and cast(Budgets.PeriodDate as Date) <= '2017-12-31'
    AND MONTH('2017-12-31') = MONTH(Budgets.PeriodDate)
WHERE Matts.MatterID  = '99999-99.003'

您也可以尝试使用APPLY操作符。。。删除左连接&它是on条件,使用outerapply并在outerapply脚本中包含on条件,如

   AND budgets.timekeeper = trans.professionals 
   AND year(budgets.perioddate) = datepart(year, transdate)
样品

OUTER APPLY
       ( 
                  SELECT     budgets.professionals AS timekeeper, 
                             budgets.amount        AS rate, 
                             budgets.perioddate 
                  FROM       matters matts 
                  INNER JOIN budgets 
                  ON         matts.matters = budgets.matters 
                  AND        cast(budgets.perioddate AS date) <= '2017-12-31' 
                  AND        month('2017-12-31') = month(budgets.perioddate) 
                  AND budgets.timekeeper = trans.professionals 
                  AND year(budgets.perioddate) = datepart(year, transdate) 
                  WHERE      matts.matterid = '99999-99.003'

                  ) AS b

感谢所有回应的人。我采纳了你的建议,并想出了一个解决办法。我在运行2小时后不得不终止的查询现在大约在14秒后完成

我在脚本开始时创建了一个cte

 ;with cte as
 (SELECT Transactions FROM Transactions t
 WHERE cast(t.TransDate as DATE) between dateadd(day, 1, DATEADD(year, -3, 
 @EndDate)) and @EndDate)
然后我将CTE链接到交易

FROM Transactions Trans
INNER JOIN cte ON cte.Transactions = Trans.Transactions 
然后,我能够删除导致问题的“where”条款

WHERE cast(transdate as DATE) between dateadd(day, 1, DATEADD(year, -3, 
@EndDate)) and @EndDate

任何人都不可能在如此少的信息上提供帮助。我们需要查看表定义,包括索引以及此处涉及的所有表的近似行数。此外,执行计划也会有所帮助,但由于您无法完成查询,这可能是不可能的。有一些明显的奇怪之处,例如,为什么您将日期转换为日期castBudgets.PeriodDate转换为日期,然后在同一字段上执行日期函数,而不使用转换MONTHBudgets.PeriodDate。在where/join中执行函数时应始终小心,因为它们可能会使任何索引的使用无效。否则,肖恩是这么说的。我猜它没有在左联接表上使用任何索引。假设您在Budgets.PeriodDate上有一个索引,但在尝试使用该列和关联索引之前,您正在对其进行转换。此时,优化器不再知道新值与索引相同,因为它可能不相同。我们肯定需要查看您的表结构、索引和估计的执行计划,因为正如Sean所说,您不会得到实际值。
WHERE cast(transdate as DATE) between dateadd(day, 1, DATEADD(year, -3, 
@EndDate)) and @EndDate