2014-02-24 68 views
1

如何避免必须在WHERE条款中一遍又一遍地输入相同的CASE WHEN...避免重复出现的情况

CASE WHEN rawGlass.blockHeight > rawGlass.blockWidth THEN rawGlass.blockWidth ELSE rawGlass.blockHeight END在此查询中经常重复。我只想做一次。我已经知道在WHERE子句中引用[Glass Height]将导致Invalid column...错误。

我意识到可能有其他解决方案不涉及使用CASE WHEN这个特定的实例,我欢迎他们,但我真的很喜欢这个问题的答案,因为我遇到了这个问题与其他查询之前的问题。

SELECT 
    parts.pgwName AS [Part Name], 
    parts.active AS [Active], 
    cutVinyl.boardName AS [Vinyl Board], 
    cutVinyl.rollWidth AS [Roll Width], 
    CASE WHEN rawGlass.blockHeight > rawGlass.blockWidth THEN rawGlass.blockWidth ELSE rawGlass.blockHeight END AS [Glass Height] 
FROM 
    parts 
     LEFT JOIN cutVinyl ON parts.vinylBoard = cutVinyl.boardName 
     LEFT JOIN rawGlass ON parts.outerSku = rawGlass.sku 
WHERE 
    (
     (cutVinyl.stretchRadius IS NOT NULL OR cutVinyl.stretchRadius = 0) AND 
     cutVinyl.rollWidth < (CASE WHEN rawGlass.blockHeight > rawGlass.blockWidth THEN rawGlass.blockWidth ELSE rawGlass.blockHeight END) 
    ) ... 


注:的情况不胜枚举一段时间,所以包裹整个WHERE子句中的一个CASE WHEN...语句,然后重复两次的条件并没有真正帮助任何。

+0

使用派生表或公用表表达式? – LittleBobbyTables

+0

什么表是blockheight和宽度?您可以将from子句中的表更改为提前设置Glass_hieght的子查询。 – Twelfth

+0

[在选择案例和where子句中避免重复性条件]可能的重复(http://stackoverflow.com/questions/12116662/avoiding-repetitive-conditions-in-the-select-case-and-where-clause) – LittleBobbyTables

回答

3

使用CROSS APPLY

SELECT 
    pgwName AS [Part Name], 
    active AS [Active], 
    boardName AS [Vinyl Board], 
    rollWidth AS [Roll Width], 
    [Glass Height] 
FROM 
    parts 
     LEFT JOIN cutVinyl ON parts.vinylBoard = cutVinyl.boardName 
     LEFT JOIN rawGlass ON parts.outerSku = rawGlass.sku 
     CROSS APPLY (
      SELECT CASE WHEN blockHeight > blockWidth THEN blockWidth 
                 ELSE blockHeight 
        END AS [Glass Height] 
     ) AS CA1 
WHERE 
    (
     (stretchRadius IS NOT NULL OR stretchRadius = 0) AND 
     rollWidth < [Glass Height]) 
    ) ... 
+0

辉煌。我从来不知道有关'CROSS APPLY'。 –

1

您可以选择用写电流的外部查询作为一个子查询是这样的:

SELECT * FROM 
(
    SELECT 
    pgwName AS [Part Name], 
    active AS [Active], 
    boardName AS [Vinyl Board], 
    rollWidth AS [Roll Width], 
    CASE WHEN blockHeight > blockWidth THEN blockWidth ELSE blockHeight END AS [Glass Height] 
    FROM 
    parts 
     LEFT JOIN cutVinyl ON parts.vinylBoard = cutVinyl.boardName 
     LEFT JOIN rawGlass ON parts.outerSku = rawGlass.sku 

) out 
WHERE 
    (
     (stretchRadius IS NOT NULL OR stretchRadius = 0) AND 
     rollWidth < Glass Height  
    ) ... 
1

我猜部分表就是这种情况下,声明来自:

... 
FROM 
parts 
    LEFT JOIN cutVinyl ON parts.vinylBoard = cutVinyl.boardName 
    LEFT JOIN (select * 
       , CASE WHEN blockHeight > blockWidth THEN blockWidth 
       ELSE blockHeight 
       END AS [Glass_Height] from rawglass) rawGlass ON parts.outerSku = rawGlass.sku 
... 

现在您可以在select语句或where语句中根据需要引用glass_height。

+0

'blockWidth'和'blockHeight'来自'rawGlass'。我将修复代码,以澄清哪些值来自哪个表。 –

+0

在修改中编辑。任何时候,当您在from子句中引用表时,您都可以引用子查询(当您点击数百万行时可能会遇到性能问题)。 – Twelfth

1

你可以使用一个custom table expression (CTE):CTE的

;WITH MyCTE AS (
SELECT 
    pgwName, 
    active, 
    boardName, 
    rollWidth, 
    CASE WHEN blockHeight > blockWidth THEN blockWidth ELSE blockHeight END AS GlassHeight, 
    stretchRadius, 
    rollWidth 

FROM 
    parts 
     LEFT JOIN cutVinyl ON parts.vinylBoard = cutVinyl.boardName 
     LEFT JOIN rawGlass ON parts.outerSku = rawGlass.sku 
) 
SELECT 
    pgwName AS [Part Name], 
    active AS [Active], 
    boardName AS [Vinyl Board], 
    rollWidth AS [Roll Width], 
    GlassHeight AS [Glass Height] 
FROM MyCTE   
WHERE 
    (
     (stretchRadius IS NOT NULL OR stretchRadius = 0) AND 
     rollWidth < GlassHeight 
    ) 

觉得作为一次性的,可链接的意见。当您需要定义要在最终查询中重用的数据子集时,它们非常有用。一旦后者被执行,它们就不复存在。他们的性能成本几乎不存在。