我需要使用MS Query在Excel 2007中显示固定管道集的每月费率,即使管道没有月费率,也必须以这种方式显示
required output http://i42.tinypic.com/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中有效,并给出以下结果
actual output http://i42.tinypic.com/5qiog.jpg
在此输出中,未显示月份没有费率的管道。因此,此代码不起作用。因此,我试图在这种情况下找到LEFT JOIN
的替代方法,以使用MS Query在excel中获得所需的输出。
协会
Pipeline和PipelineRate - 可选的一对多关系
PipelineRate和PipelineRateHistory - 可选的一对多关系
任何人都可以建议左连接的替代方法或实现此目的的方法吗?
PS:我无法使用存储过程。我知道如何使用VBA执行此操作。我需要使用MS Query
来完成此任务答案 0 :(得分:0)
尝试:
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调用存储过程。从阅读开始,似乎可能是如何确定和编号参数的问题。
答案 1 :(得分:0)
也许只是ODBC尝试重写您的查询失败了。我不知道为什么ON
版本不起作用,但你必须在WHERE
中包含空值。 Nulls并不等同于任何东西,因此=
正在删除带有空值的行。
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]
答案 2 :(得分:0)
根据您的第一个查询,您尝试将月份过滤器放在左侧连接中。 由于这是左连接您的获取记录月份和年份过滤器不是强制性的。
但是在下一个查询中,你将过滤器放在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 (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]