2011-09-16 62 views
1

如果你有一个类似于这样的查询有没有更好的方法?有没有一种替代方法来处理所有的“或”语句?只是想figureout一种方式来摆脱所有的“手术室”更好的写法查询方式

版本的: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 
) 
+1

这样的气味就像可怕的餐桌设计,你需要规范事情。 –

+0

你是对的....我不能控制数据模型不幸的是....你是对的,虽然它很烂。 – scarpacci

+0

什么是数据类型? BIT,INT,...?你可以添加列到表中? –

回答

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; 
+0

那是我唯一想到的东西,就是类似的东西....就像做了所有这些事情的总和,并检查> 0。谢谢Aaron。 – scarpacci

+0

注意负数,他们可以将其调平到0或更低 –

+0

'Attribute1 |属性2 |属性3 ... <> 0'? –

1

它看起来像你的数据库不被标准化。

让我们来看看目前的方案。你有这样的事,对吧?

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

有了这样一张表,or s是要走的路。我的意思是:还有其他同样尴尬的构造,但可能会使用更复杂的构造,但在以合理的方式构造数据之前,您将被迫通过大量这些问题。

我会带你走过规范这部分模式的过程,同时我会放弃一些有用的链接。

你想有两个表,而不是:一个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 | 

见我们去做什么了?我们做到这一点,所以product将与product_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条目。

+0

我同意你的意见,但OP说他不能改变模式。 –

+0

@Aaron:是的,现在看到了--.-' – cbrandolino

1

虽然这似乎丑陋,这只是一个UNPIVOT做了两次,这当然可以通过意见简化。第一个unpivot子查询为您提供了您的Attributes列,外部的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 
+0

你*爱* unpivots,你呢? :) – cbrandolino

+0

不特别。我只是每天都用这种垃圾数据。 8-) – Sumo

0

只是一个快速的思想,总结了所有的人,看看结果是大于,请确保您的情况的读取绝对值有任何负数。

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

相关问题