0

如何使以下 T-SQL 语句合法?我可以复制为每个 CASE 选项设置 @Type 变量的子查询,但我宁愿只执行一次子查询。可能吗?

SELECT
      @Type = (SELECT CustomerType FROM dbo.Customers WHERE CustomerId = (SELECT CustomerId FROM dbo.CustomerCategories WHERE CatId= @CatId)),
      CASE
         WHEN @Type = 'Consumer'THEN dbo.Products.FriendlyName
         WHEN @Type = 'Company' THEN dbo.Products.BusinessName
         WHEN @Type IS NULL THEN dbo.Products.FriendlyName
         WHEN @Type = '' THEN dbo.Products.FriendlyName
      END Product,
      ...
FROM
      Products
INNER JOIN
      Category
...

编辑:将我的示例修改为更具体...现在必须运行...明天会回来...抱歉短签但必须接孩子:D 明天再回来查看。谢谢!!

澄清:我不能将两者分开:在子查询的 where 子句中,我需要引用主查询的 join stmt 中使用的表中的列。如果我将它们分开,那么 @Type 将失去相关性。

4

2 回答 2

4

为什么不把它分成两个操作呢?您认为通过将它们整合到一个语句中可以获得什么?

SELECT @Type = (subquery);

SELECT CASE WHEN @type = 'Consumer'...

冒着听起来迟钝的风险,你真的需要这个变量吗?为什么不:

SELECT CASE WHEN col_form_subquery = 'Consumer' THEN ...
  END Product
FROM (<subquery>) AS x;

使用该表单,您需要决定是要为变量赋值还是检索结果。

您还可以提取多个变量,例如

SELECT @Col1 = Col1, @Col2 = Col2
  FROM (<subquery>) AS x;

-- then refer to those variables in your other query:

SELECT *, @Col1, @Col2 FROM dbo.Products WHERE Col1 = @Col2;

但这都是猜测,因为您没有分享足够的细节。

编辑好吧,既然我们有一个真正的查询并且可以更好地理解你所追求的,让我们看看我们是否可以为你写一个新版本。我假设您只是尝试存储 @Type 变量,以便您可以在查询中重新使用它,并且您没有尝试将值存储在那里以供以后使用(在此查询之后)。

SELECT CASE 
      WHEN c.CustomerType = 'Company' THEN p.BusinessName
      WHEN COALESCE(c.CustomerType, '') IN ('Consumer', '') THEN p.FriendlyName
    END
    --, other columns
FROM dbo.Products AS p
INNER JOIN dbo.Category AS cat 
  ON p.CatId = cat.CatId
INNER JOIN dbo.CustomerCategories AS ccat
  ON ccat.CatId = cat.CatId
INNER JOIN dbo.Customers AS c
  ON c.CustomerId = ccat.CustomerId
WHERE cat.CategoryId = @CatId;

一些注意事项:

  • 我不确定您为什么认为子查询是解决此问题的正确方法。通常,构建适当的连接并让 SQL Server 整体优化查询要好得多(对其他开发人员来说也更清楚),而不是试图变得聪明并在很大程度上独立于主查询来优化单个子查询。正确的连接将有助于预先消除行,否则这些行可能会通过子查询被物化 - 只会被丢弃。信任 SQL Server 来完成它的工作,在这种情况下,它的工作是跨多个表执行连接。
  • 如果 SELECT 不需要显示类别名称,则可能不需要加入 dbo.Category。如果是这样,则更改 where 子句并删除该连接(改为连接到 CusomterCategories)。
  • 如果您已经涵盖了所有可能的情况,则可以将第二种情况更改为简单的 ELSE。
  • 我对 Products 和 Category 之间的连接做了一个假设(为什么 Category 不像其他的那样是复数的?)。如果不是这样,请填写我们。
于 2012-04-24T19:42:15.883 回答
4

你不能不这样做,你会得到以下错误

为变量赋值的 SELECT 语句不得与数据检索操作结合使用。

将两者分开,然后将变量作为 select 语句的一部分返回

于 2012-04-24T19:42:15.977 回答