查找列的最大值和最小值并更新第一列sql server

时间:2016-11-14 06:00:48

标签: sql-server sql-server-2012 aggregate-functions

根据产品和产品密钥,更新列ord_by。产品和product_key应该只有一分钟和最大值。

E.g: Table


  +-------------+---------+-------+--------+
| Product_key | product | price | ord_by |
+-------------+---------+-------+--------+
|           1 | ABC     |    10 |        |
|           1 | ABC     |    10 |        |
|           1 | ABC     |    20 |        |
|           1 | ABC     |   100 |        |
|           1 | ABC     |   100 |        |
|           2 | EFG     |    20 |        |
|           2 | EFG     |    40 |        |
|           3 | ABC     |   100 |        |
+-------------+---------+-------+--------+

Expected output:
+-------------+---------+-------+--------+
| Product_key | product | price | ord_by |
+-------------+---------+-------+--------+
|           1 | ABC     |    10 | Min    |
|           1 | ABC     |    10 | Mid    |
|           1 | ABC     |    20 | Mid    |
|           1 | ABC     |   100 | Mid    |
|           1 | ABC     |   100 | Max    |
|           2 | EFG     |    20 | Min    |
|           2 | EFG     |    40 | Max    |
|           3 | ABC     |   100 | None   |
+-------------+---------+-------+--------+

我的尝试:

;WITH ord_cte
            AS (
                SELECT product
                    ,product_key
                    ,max(price) as max_price
                    ,min(price) as min_price
                FROM t_prod_ord

                group by   product,product_key

                )
            UPDATE t1
SET ord_by = case 
when t2.max_price =t2.min_price then 'none' 
when t2.max_price=t1.price then 'max' 
when t2.min_price=t1.price then 'min'  
else 'mid' end 
            FROM t_prod_ord t1
            INNER JOIN ord_cte t2 ON t1.product_key = t2.product_key   and t1.product=t2.product

使用此查询,它会为列ord_by更新多个最大值和最小值。

2 个答案:

答案 0 :(得分:3)

Product_keyPrice顺序,按ASC生成每个DESC订单的行号。然后使用CASE语句中的行号查找Min/Max

Count() Over()汇总窗口函数可帮助您找到每个Product_key的总数,我们可以使用它来查找None

这是一种方式

;WITH cte
     AS (SELECT *,
                Row_number()OVER(PARTITION BY Product_key ORDER BY price) AS Min_KEY,
                Row_number()OVER(PARTITION BY Product_key ORDER BY price DESC) AS Max_KEY,
                Count(1)OVER(partition BY Product_key) AS cnt
         FROM   Yourtable)
SELECT Product_key,
       product,
       price,
       CASE
         WHEN cnt = 1 THEN 'None'
         WHEN Min_KEY = 1 THEN 'Min'
         WHEN Max_Key = 1 THEN 'Max'
         ELSE 'Mid'
       END
FROM   cte 

答案 1 :(得分:1)

另一种处理cte ...

的方法
 SELECT [Product_key],
           [product],
           [price],
           CASE
           WHEN Max(RN)
                    OVER(
                      PARTITION BY PRODUCT_KEY, PRODUCT
                      )=1 AND RN=1 THEN 'NONE'
             WHEN Min(RN)
                    OVER(
                      PARTITION BY PRODUCT_KEY, PRODUCT
                     ) = RN THEN 'MIN'
             WHEN Max(RN)
                    OVER(
                      PARTITION BY PRODUCT_KEY, PRODUCT
                      ) = RN THEN 'MAX'

             ELSE 'MID'
           END ORDER_BY
    FROM   (SELECT *,
                   Row_number()
                     OVER(
                       PARTITION BY PRODUCT_KEY, PRODUCT
                       ORDER BY PRICE) RN
            FROM   TABLE1)Z