2017-08-31 33 views
0

我有一個這樣的表,其中,假設爲了舉例,NAME是唯一標識符。僅使用SQL中的MAX函數更新重複行

NAME AGE   VALUE 
Jack Under 65 3 
Jack 66-74  5 
John 66-74  7 
John Over 75  9 
Gill 25-35  11 

一些NAME■找一個以上AGE,這是不希望的,因爲這是由於數據的髒度。

我的目標是更新副本只在每個NAME內有一個AGE。所需的輸出是這樣的:

NAME AGE   VALUE 
Jack Under 65 3 
Jack Under 65 5 
John 66-74  7 
John 66-74  9 
Gill 25-35  11 

事情是這樣的UPDATE語句應該工作,但事實並非如此。

UPDATE table t1 
SET t1.age=MAX(t1.age) 
WHERE EXISTS (SELECT COUNT(t2.AGE) 
       FROM table t2 
       WHERE t1.NAME=t2.NAME 
       GROUP BY t2.NAME 
       HAVING COUNT(t2.AGE) > 1) 

SQL Error: ORA-00934: group function is not allowed here 

第二期

即使我得到了上述說法的工作,還有第二個問題。想法是使用字符串上的MAX(或MIN)函數爲組中的所有重複設置相同的值。

但不幸的是,這也不會如預期般工作。爲了保持一致性,理想情況下,年齡將默認爲最低年齡段。但由於MAX/MIN對字符串比較字母順序,這將給予,如:

  • 「66-74」 和 「65歲以下」=> MAX = 「65歲以下」 - 最低
  • 「66-74」和「超過75」=> MAX =「超過75」 - 最高

只有四個年齡組,可以指定自定義順序嗎?

  • NB1:我使用Oracle SQL。
  • NB2:我不介意是否有辦法使用SELECT而不是UPDATE語句來實現結果。

重複的例子,

SELECT 'Jack' as NAME, 'Under 65' as AGE, 3 as VALUE from dual 
UNION ALL 
SELECT 'Jack' as NAME, '66-74' as AGE, 5 as VALUE from dual 
UNION ALL 
SELECT 'John' as NAME, '66-74' as AGE, 7 as VALUE from dual 
UNION ALL 
SELECT 'John' as NAME, 'Over 75' as AGE, 9 as VALUE from dual 
UNION ALL 
SELECT 'Gill' as NAME, '25-35' as AGE, 11 as VALUE from dual 
+1

您更新查詢將需要邏輯選擇重複的情況下,更小的年齡,但考慮到它的存儲爲文本,有時在裏面的話,這可能會導致挑戰性的查詢 –

+0

**唯一標識符**的絕佳示例! – mathguy

回答

1

您可以case when條款定義自定義的順序,然後使用分析max()。這個工作對給定的例子:

update t1 set age = (
    select max(age) keep (dense_rank last 
      order by case when age = 'Over 75' then 1 
         when age = '66-74' then 2 
         when age = 'Under 65' then 3 
         when age = '25-35' then 4 
        end) 
    from t1 tx where tx.name = t1.name) 
+0

就像一個魅力工作! – Mihael