如何更新除组中的最大值之外的所有内容

时间:2017-12-05 03:47:27

标签: sql oracle

我有下表:

+----+----------+-----+-------
| ID | animal| pets | age  
+----+----------+-----+------
|  1 | pig   | y    | 19
|  2 | pig   | y    | 21
|  3 | horse | y    | 23
|  4 | dog   | y    | 45
|  5 | dog   | y    | 56
|  6 | cat   | n    | 34
|  7 | cat   | y    | 56

我需要帮助构建一个查询,将“宠物”设置为“n”,表示该种动物的行数小于设置为“y”的动物的最大年龄值。因此,每个动物只能有一行设置为'y',并且必须是具有最大年龄的那一行,所以结果表应该如下所示:

+----+----------+-----+-------
| ID | animal| pets | age  
+----+----------+-----+------
|  1 | pig   | n    | 19
|  2 | pig   | y    | 21
|  3 | horse | y    | 23
|  4 | dog   | n    | 45
|  5 | dog   | y    | 56
|  6 | cat   | n    | 34
|  7 | cat   | y    | 56

3 个答案:

答案 0 :(得分:0)

尝试这个:您可以使用subquery,但如果年龄相同,则不会更新:

UPDATE temp SET pets = 'n'
WHERE age in ( SELECT t.age
FROM temp t
INNER JOIN (SELECT animal, MAX(age) age 
            FROM temp GROUP BY animal) t1 ON t1.animal = t.animal AND t1.age <> t.age)

答案 1 :(得分:0)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE Pets
    (ID int, ANIMAL varchar2(5), PETS varchar2(1), AGE int)
;

INSERT ALL 
    INTO Pets (ID, ANIMAL, PETS, AGE)
         VALUES (1, 'pig', 'y', 19)
    INTO Pets (ID, ANIMAL, PETS, AGE)
         VALUES (2, 'pig', 'y', 21)
    INTO Pets (ID, ANIMAL, PETS, AGE)
         VALUES (3, 'horse', 'y', 23)
    INTO Pets (ID, ANIMAL, PETS, AGE)
         VALUES (4, 'dog', 'y', 45)
    INTO Pets (ID, ANIMAL, PETS, AGE)
         VALUES (5, 'dog', 'y', 56)
    INTO Pets (ID, ANIMAL, PETS, AGE)
         VALUES (6, 'cat', 'n', 34)
    INTO Pets (ID, ANIMAL, PETS, AGE)
         VALUES (7, 'cat', 'y', 56)
SELECT * FROM dual
;

查询1

update pets
set pets = case when age = (select max(age) from pets p where pets.animal = p.animal)
                then 'Y' 
                else 'N' 
           end
;

<强> Results

select
*
from pets

| ID | ANIMAL | PETS | AGE |
|----|--------|------|-----|
|  1 |    pig |    N |  19 |
|  2 |    pig |    Y |  21 |
|  3 |  horse |    Y |  23 |
|  4 |    dog |    N |  45 |
|  5 |    dog |    Y |  56 |
|  6 |    cat |    N |  34 |
|  7 |    cat |    Y |  56 |

我不确定为什么你需要这个作为更新。视图会更简单,例如。

select ID, ANIMAL, AGE
      , case when AGE = max(AGE) over(partition by animal) then 'Y' else 'N' end pets_2
from pets

答案 2 :(得分:0)

您可以使用此代码

 update your_table_name a 
 inner join your_table_name b on a.animal = b.animal
 set a.pet='n' 
 where a.age < (select max(b.age));