编写查询的更好方法

时间:2011-09-16 03:28:14

标签: sql-server sql-server-2008

如果你有一个类似的查询是否有更好的方法?是否有另一种方法来处理所有“OR”语句?试图找出一种摆脱所有“OR”的方法

版本:SQL Server 2008 R2

Select ProductID
From product.Products
Where 
(Attribute1 <> 0
or Attribute2 <> 0
or Attribute3 <> 0
or Attribute4 <> 0
or Attribute5 <> 0
or Attribute6 <> 0
or Attribute7 <> 0
or Attribute8 <> 0
)
AND
(CatAttrib1 <> 0
or CatAttrib2 <> 0
or CatAttrib3 <> 0
)

4 个答案:

答案 0 :(得分:3)

您可以创建一个视图,例如(假设属性列是基于INT的,而不是BIT):

CREATE VIEW product.ViewProducts
AS
    SELECT Attribute1, Attribute2, ...
       Attributes = CASE 
            WHEN Attribute1 + Attribute2 + Attribute3 ... > 0 
            THEN 1 ELSE 0 END,
       CatAttrib1, CatAttrib2, ..., 
       CatAttribs = CASE
            WHEN CatAttrib1 + CatAttrib2 + CatAttrib3 ... > 0
            THEN 1 ELSE 0 END
    FROM product.Products;
GO

现在你可以说:

SELECT ProductID
  FROM product.Products
  WHERE Attributes = 1
  AND CatAttribs = 1;

答案 1 :(得分:1)

看起来你的数据库没有规范化。

让我们来看看当前的方案。你有类似的东西,对吧?

| id | name | attribute1| attribute2 | attribute3 | ... | 
--------------------------------------------------------
| 1  | car1 |     1     |      2     |     0      | ... |

使用这样的表格,or是可行的方法。我的意思是:还有其他同样笨拙的结构,但你可能会使用更复杂的结构,但在你以合理的方式构建数据之前,你将被迫通过大量的这些问题。

我将引导您完成规范化这部分模式的过程,同时我会删除一些有用的链接。

您希望有两个表:一个product表,如下所示:

| id | name |

一个product_attribute表类似于以下内容:

| product_id | attribute | value |

上面的示例记录将在新结构中表示:

product

| id | name | 
-------------
| 1  | car1 |

product_attribute

| product_id | attribute | value |
----------------------------------
|      1     |     1     |   1   |
|      1     |     2     |   2   |
|      1     |     3     |   0   |

看看我们在那里做了什么?我们这样做是因为productproduct_attributesone-to-many的关系。此模式现在遵循First Normal Form,因为我们不再是repeating groups across columns

让我们回到您的查询:您想要选择没有零值属性的每个product。所以,我们加入了两个表格(这样每个product都会连接到product_attribute s)并进行过滤:

 SELECT * FROM product 
   JOIN product_attribute
     ON (product.id = product_attribute.product_id)
   WHERE product_attribute.value <> 0

看起来更干净,是吗?

Here是SQL Server连接上的msdn条目。

答案 2 :(得分:1)

虽然这个似乎丑陋,但这只是UNPIVOT做了两次,当然可以通过视图简化。第一个unpivot子查询为您提供属性列,外部unpivot为您提供CatAttribs列。然后,您可以在最后执行一个简单的WHERE子句。

SELECT DISTINCT
        ProductID
        --,Attributes
        --,CatAttributes
    FROM
        (
            SELECT 
                    ProductID
                    ,Attributes
                    ,CatAttrib1
                    ,CatAttrib2
                    ,CatAttrib3
                FROM
                    (
                    SELECT 
                            ProductID
                            ,Attribute1
                            ,Attribute2
                            ,Attribute3
                            ,Attribute4
                            ,Attribute5
                            ,Attribute6
                            ,Attribute7
                            ,Attribute8
                            ,CatAttrib1
                            ,CatAttrib2
                            ,CatAttrib3
                        FROM 
                            product.Products) a
            UNPIVOT
                (
                Attributes FOR product.Products IN
                    (
                        Attribute1
                        ,Attribute2
                        ,Attribute3
                        ,Attribute4
                        ,Attribute5
                        ,Attribute6
                        ,Attribute7
                        ,Attribute8
                    )
                ) AS attrUnpivot
        ) c
UNPIVOT
    (
    CatAttributes FOR product.Products IN
        (
            CatAttrib1
            ,CatAttrib2
            ,CatAttrib3
        )
    ) AS catUnpivot
WHERE
    ProductID = catUnpivot.ProductID
    AND Attributes <> 0
    AND CatAttributes <> 0

答案 3 :(得分:0)

只是快速思考,总结所有这些并查看结​​果是否大于,请确保在有任何负数的情况下读取绝对值。

但是我不太确定,如果你想在这里赢得任何表现,但查询可能看起来有点整洁。