避免重复的情况

时间:2014-02-24 18:01:45

标签: sql case sql-server-2008-express simplify

如何避免在CASE WHEN...子句中反复输入相同的WHERE

CASE WHEN rawGlass.blockHeight > rawGlass.blockWidth THEN rawGlass.blockWidth ELSE rawGlass.blockHeight END在此查询中经常重复。我只想做一次。我已经知道在[Glass Height]子句中引用WHERE会导致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...语句中,然后重复两次条件真的有帮助。

4 个答案:

答案 0 :(得分: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])
    ) ...

答案 1 :(得分:1)

您可以选择使用current作为子查询编写外部查询,如下所示:

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    
   ) ...

答案 2 :(得分: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。

答案 3 :(得分:1)

您可以使用custom table expression (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 
    )

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