【问题标题】:Correlated join with outer fields as parameters以外部字段作为参数的相关连接
【发布时间】:2011-08-11 07:57:44
【问题描述】:

我需要一种将表格与函数结果连接起来的方法。我不确定这是否可能,不知何故我认为这不是一个好主意。让我试着解释一下情况。

有一个表[Entities]:

[ID]    [Description]    [kWh]    [kVArh]    [kVAh]    [OfferID]    [CustomOfferID]

另一个表[数据]:

[ID]    [Timestamp]    [Value]

还有一个功能:

[Calc] (@offer, @customOffer, @kWh, @kVArh, @kVAh, @dtStart, @dtEnd)

所以你可以看到有实体,实体的数据(使用)和一个计算成本的函数。

我需要显示多个实体的使用情况和成本:

[Description]    [MWh]    [MVA]    [Cost]

[MWh] 将是该期间所有实体数据的总和; [MVA] 将是该期间所有数据的最大值;而[Cost] 将对子查询(函数)中的[Cost] 字段求和。

我认为可以完成工作的查询如下所示:

SELECT [tc].[ID], [tc].[Desc]
    , SUM([kWh].[Value]) / 1000 AS [MWh]
    , MAX([kVAh].[Value]) / 1000 AS [MVA]
    , SUM([cost].[Cost])
FROM [Tree_Cost] AS [tc]
INNER JOIN [Data] AS [kWh] ON [tc].[kWh] = [kWh].[ID]
INNER JOIN [Data] AS [kVAh] ON [tc].[kVAh] = [kVAh].[ID]
INNER JOIN
(
    SELECT [tc].[ID], [Cost]
    FROM [Calc] ([tc].[Offer_ID], [tc].[OfferCustom_ID], [tc].[kWh], [tc].[KVArh], [tc].[kVAh], @dtStart, @dtEnd)
) AS [cost] ON [tc].[ID] = [cost].[ID]
WHERE [tc].[Type] = 1 AND [tc].[TypeDesc] = 'GF_K_M'
AND [kWh].[Timestamp] BETWEEN @dtStart AND @dtEnd
AND [kVAh].[Timestamp] BETWEEN @dtStart AND @dtEnd
GROUP BY [tc].[ID], [tc].[Desc]

这里真正的问题是我需要将外部查询中的[ID] 包含在内部查询(函数)的结果集中,以便能够连接两者。然后我还需要能够将外部查询中的字段用作内部查询(函数)的参数。

这显然不是在内部查询中无法识别[tc] 标识符的方式。那么我应该如何完成这样的事情呢?


CREATE FUNCTION [dbo].[Calc]
  ( \@intOffer [int]
  , \@intCustom [int]
  , \@intP [int]
  , \@intQ [int]
  , \@intS [int]
  , \@dtStart [datetime]
  , \@dtEnd [datetime]
  )
RETURNS TABLE
      ( [Entry] [nvarchar](200) NULL
      , [Rate] [float] NULL
      , [Unit] [nvarchar](50) NULL
      , [Reading] [float] NULL
      , [Cost] [float] NULL
      , [DDate] [nvarchar](50) NULL
      )
WITH EXECUTE AS CALLER
  AS EXTERNAL NAME [OfferCalcLite].[UserDefinedFunctions].[SqlArray]

【问题讨论】:

  • @ypercube: "还有一个函数:[Calc] (@offer, @customOffer, @kWh, @kVArh, @kVAh, @dtStart, @dtEnd)"
  • @cularis:我试图弄清楚这个函数的使用位置。 @that0th3rGuy:是用来计算[Cost]的吗?
  • 是的,[Calc] 是一个函数,它是具有字段[Description] [Unit] [Rate] [Cost] [Comment] 的数据库,它返回几行;很抱歉没有开始清楚这一点。那么[Cost](在主查询中),我想,可以用SUM生成
  • 你能发布[Calc]的定义吗?
  • 对不起,根据定义,您的意思是(抱歉格式不正确):CREATE FUNCTION [dbo].[Calc](\@intOffer [int], \@intCustom [int], \@intP [int], \@intQ [int], \@intS [int], \@dtStart [datetime], \@dtEnd [datetime]) 返回表 ([Entry] [nvarchar](200) NULL, [ Rate] [float] NULL, [Unit] [nvarchar](50) NULL, [Reading] [float] NULL, [Cost] [float] NULL, [DDate] [nvarchar](50) NULL ) WITH EXECUTE AS CALLER AS外部名称 [OfferCalcLite].[UserDefinedFunctions].[SqlArray]

标签: sql join correlated-subquery


【解决方案1】:

我不确定我是否理解正确。也许您可以完全放弃 JOIN:

INNER JOIN
(
    SELECT [tc].[ID], [Cost]
    FROM [Calc] ([tc].[Offer_ID], [tc].[OfferCustom_ID], [tc].[kWh], [tc].[KVArh], [tc].[kVAh], @dtStart, @dtEnd)
) AS [cost] ON [tc].[ID] = [cost].[ID]

并改变:

, SUM([cost].[Cost])

进入:

, SUM( [Calc] ( [tc].[Offer_ID]
              , [tc].[OfferCustom_ID]
              , [tc].[kWh]
              , [tc].[KVArh]
              , [tc].[kVAh]
              , @dtStart, @dtEnd
              )
     ) AS Cost

【讨论】:

  • 感谢您的回复。我很抱歉之前没有开始清楚。 [Calc] 函数返回一个包含多列的结果集,因此我将您的建议更改如下:, ( SELECT SUM([Cost]) AS [Cost] FROM [Calc] (...)) AS [Cost] 尽管它产生了错误:“...无法产生查询计划。”;我会试着看看我能找到关于这个错误的信息。再次感谢。
  • 我得到“不正确的语法”。 SELECT SUM(<function>({arguments})) 其中<function>({arguments}) 返回的多列是否有效?我不需要指定要求和的列吗?
  • 好的,如果你可以创建另一个只返回一个结果的函数(比如CalcCost),那么你可以使用我的建议。
  • 可以工作,但不幸的是新功能不是一个选项。但是,我找到了解决方案。它涉及我改变的你的建议。 “无法生成查询计划”错误的原因是因为我使用外部查询的字段作为参数,但我没有将它们包含在 GROUP BY 子句中。谢谢你的时间!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-30
  • 2011-06-14
  • 1970-01-01
相关资源
最近更新 更多