2012-04-24 86 views
0

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

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-clasue中,我需要引用表中的主要查询的join stmt中使用的列。如果我将它们分开,那么@Type将失去相关性。

+0

你需要更具体的一部分。 – 2012-04-24 19:53:20

+0

你仍然太模糊。请告诉我们你需要做什么,而不是告诉我们你认为你需要做什么。我认为这里有一个关于查询和变量如何工作的根本缺失的链接,但是如果您向我们展示示例数据和期望的结果,那么我们是非常聪明的人,并且可能想出如何实现您所追求的内容。 – 2012-04-24 20:03:22

+0

如果您指定您正在使用的SQL Server的版本,这也很有用! – 2012-04-24 20:07:39

回答

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。
  • 我对产品和类别之间的联系做了一个假设(为什么类别不像其他类型那样是复数?)。如果这不是,请填写我们。
+0

不能将它们分开。需要他们一起进行设置操作。 – Laguna 2012-04-24 19:46:50

+0

你能解释一下你认为“set-operation”的含义吗? – 2012-04-24 19:55:55

+0

大声笑(我在嘲笑自己)...基本上我的意思是在子查询的where-clasue中,我需要引用主表中用于主查询的表中的列连接...我知道它可能还不清楚请让我知道任何我可以澄清的细节。谢谢! – Laguna 2012-04-24 19:59:59

4

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

一个值赋给变量不能与数据检索操作结合

的SELECT语句。

将二者分开,然后返回变量作为select语句

+0

不能将它们分开。需要他们一起进行设置操作。 – Laguna 2012-04-24 19:47:08

+2

您无法为变量赋值并同时返回结果集 – SQLMenace 2012-04-24 19:51:06

+0

需要了解的内容。谢谢。有没有办法避免多次执行子查询? – Laguna 2012-04-24 19:52:18

相关问题