将参数传递给子查询

新手上路,请多包涵

我在 Visual Studio 2015 和 SQL Server 2014 中使用 SSRS/SSDT。存在一个超过 8 年的错误, 您无法从具有相同名称的不同表中选择多个列。为了解决这个问题,我需要使用子查询。我找到的每一个答案都会重写给定的查询以删除子查询,这通常很好,但 在这种情况下不适用。如何将参数传递给 SQL Server 中的子查询?

列别名不适用于此错误 - 使用 AS 在“重复”列上返回未知列错误,即使它适用于所有其他列。 SELECT 子句中的最后两行有效,因为正在查询值,因此报告可以使用它们,但实际查询的其余部分不使用它们。

这是我当前的代码(不起作用,因为子查询返回多行)。

 SELECT t.[Description],
       t.RequestedCompletionDate,
       t.CommitDate,
       t.StatusId,
       t.PriorityId,
       p.ProjectNumber,
       s.Name AS StatusDescription,
       pr.Name AS PriorityDescription
FROM ProjectTask t
inner join Project p
    on p.Id = t.ProjectId
inner join Project_TaskStatus s
    on s.Id = t.StatusId
inner join Project_Priority pr
    on pr.Id = t.PriorityId
WHERE t.Type = 'ET'
AND t.StatusId NOT IN (4,7)
AND
(
    SELECT StatusId FROM Project
    -- WHERE ?
)
NOT IN (3, 4)
ORDER BY t.PriorityId,
         t.CommitDate,
         t.RequestedCompletionDate

这是注释中要求的具有别名的代码。它抛出一个错误:

 SELECT t.[Description],
       t.RequestedCompletionDate,
       t.CommitDate,
       t.StatusId AS TaskStatusId,
       t.PriorityId,
       p.ProjectNumber,
       p.StatusId AS ProjectStatusId,
       s.Name AS StatusDescription,
       pr.Name AS PriorityDescription
FROM ProjectTask t
inner join Project p
    on p.Id = t.ProjectId
inner join Project_TaskStatus s
    on s.Id = TaskStatusId
inner join Project_Priority pr
    on pr.Id = t.PriorityId
WHERE t.Type = 'ET'
AND TaskStatusId NOT IN (4,7)
AND ProjectStatusId NOT IN (3,4)
ORDER BY t.PriorityId,
         t.CommitDate,
         t.RequestedCompletionDate

-- Invalid column name 'TaskStatusId'.
-- Invalid column name 'TaskStatusId'.
-- Invalid column name 'TaskStatusId'.
-- Invalid column name 'ProjectStatusId'.
-- Invalid column name 'ProjectStatusId'.

理想的代码如下,但它会抛出错误 An item with the same key has already been added ,这是 SSRS/SSDT 在尝试返回多个同名列时抛出的错误。

 SELECT t.[Description],
       t.RequestedCompletionDate,
       t.CommitDate,
       t.StatusId,
       t.PriorityId,
       p.ProjectNumber,
       p.StatusId,
       s.Name AS StatusDescription,
       pr.Name AS PriorityDescription
FROM ProjectTask t
inner join Project p
    on p.Id = t.ProjectId
inner join Project_TaskStatus s
    on s.Id = t.StatusId
inner join Project_Priority pr
    on pr.Id = t.PriorityId
WHERE t.Type = 'ET'
AND t.StatusId NOT IN (4,7)
AND p.StatusId NOT IN (3,4)
ORDER BY t.PriorityId,
         t.CommitDate,
         t.RequestedCompletionDate

原文由 vaindil 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 878
2 个回答

我对此感到非常愚蠢,但显然它可以在子查询中调用 p.Id 。它知道我正在引用父查询的值,即使它在子查询中。感谢大家的帮助。

 SELECT t.[Description],
       t.RequestedCompletionDate,
       t.CommitDate,
       t.StatusId,
       t.PriorityId,
       p.ProjectNumber,
       s.Name AS StatusDescription,
       pr.Name AS PriorityDescription
FROM ProjectTask t
inner join Project p
    on p.Id = t.ProjectId
inner join Project_TaskStatus s
    on s.Id = t.StatusId
inner join Project_Priority pr
    on pr.Id = t.PriorityId
WHERE t.Type = 'ET'
AND t.StatusId NOT IN (4,7)
AND
(
    SELECT StatusId FROM Project WHERE Id = p.Id
)
NOT IN (3, 4)
ORDER BY t.PriorityId,
         t.CommitDate,
         t.RequestedCompletionDate

原文由 vaindil 发布,翻译遵循 CC BY-SA 3.0 许可协议

当前代码(不起作用,因为子查询返回多行)。

所以代替这个

AND
(
    SELECT StatusId FROM Project
    -- WHERE ?
)
NOT IN (3, 4)

你可以做

AND
EXISTS (
    SELECT 1 FROM Project p2
    WHERE p2.StatusId IN (3, 4) AND p2.Id = p.Id
)

原文由 radoh 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进