过滤相同的值 - 只需一个 - 不使用CTE

时间:2014-03-06 13:03:10

标签: sql sql-server filter

我有下表(我在简单的日期过滤查询后得到)

现在我想显示给定月份的SalesAmount,虽然在某些情况下我有相同ID的多个值,在这种情况下,一个需要被忽略而另一个需要,否则(如果只有一个条目)对于ID,应该采用该值)

| TableID |SalesOpportunityID| OrderID | SalesCycleStatus | Status | SalesAmount | OrderIncMonth |
|    1    |   14551          |  NULL   |     Oppurtunity  |  Lost  |    1556,316 |     2013-10   |
|    2    |   12551          |  14515  |       Order      | Active |   23563,23  |     2013-10   |
|    3    |   12151          |  15131  |       Order      | Active |  2212352,43 |     2013-10   |
|    4    |   14531          |  NULL   |     Opportunity  |  Lost  | 32152332,1  |     2013-10   |

|    5    |   12651          |  NULL   |     Opportunity  |  Won   |   23525,3245|     2013-10   |
|    6    |   12651          |  21452  |       Order      | Active |   23525,3245|     2013-10   |

如您所见,TableID = 5和= 6基本相同,

只是存储为Sales Opurtunity,而不是(在赢得之后)变成订单并再次存储, 因为我试图计算本月所有机会和订单的总和,

我需要过滤掉这些双值,并通过以下方式进行:仅获取SalesCycleStatus所在的SalesOpportunityID的值=订单

(如果有诅咒,则有2个条目具有相同的SalesOpportunityID,否则请使用SalesAmount for SalesOpportunityID - 考虑天气,SalesCycleStatus是订单或机会)

有没有办法在不使用CTE的情况下执行此操作? 非常感谢你的帮助:)!

2 个答案:

答案 0 :(得分:1)

有很多方法可以做到这一点:我建议的第一个方法是使用NOT EXISTS的子查询,如下所示:

SELECT TableID, SalesOpportunityID, OrderID, SalesCycleStatus, Status, SalesAmount 
FROM TestTable 
WHERE 
  SalesCycleStatus = 'Order' OR
  NOT EXISTS
    (
      SELECT TableID 
      FROM TestTable sub 
      WHERE 
        SalesCycleStatus = 'Order' AND
        sub.SalesOpportunityID = TestTable.SalesOpportunityID
    )

点击此处查看完整的SQL Fiddle示例

答案 1 :(得分:1)

您也可以使用ROW_NUNBER()来实现这一点,因为它只需要一次表扫描,因此效率更高:

SELECT  TableID, 
        SalesOpportunityID, 
        OrderID, 
        SalesCycleStatus, 
        Status, 
        SalesAmount
FROM (  SELECT  TableID, 
                SalesOpportunityID, 
                OrderID, 
                SalesCycleStatus, 
                Status, 
                SalesAmount ,
                RowNumber = ROW_NUMBER() OVER(PARTITION BY SalesOpportunityID 
                                                ORDER BY CASE WHEN SalesCycleStatus = 'Order' THEN 1 ELSE 0 END, TableID)
        FROM    T
    ) t
WHERE t.RowNumber = 1;