2014-10-31 63 views
0

MY_TABLE會是這樣的:僅當在不同字段中存在具有給定值的多行時,才更新記錄集中的列?

user_id shared_field bool_field 
------- ------------ ---------- 
1  abc   null 
2  def   null 
3  ghi   Y 
4  ghi   null 
5  ghi   null 
6  abc   Y 
7  jkl   null 

如果誰共享與其他用戶一樣shared_field(如USER_ID 3,4,5以上)的用戶的bool_field變化,只有一個用戶應該有'Y'。其餘的應該在bool_field列中有空值。例如,如果user_id 4現在應該具有'Y',則必須將user_id 4的bool_field更改爲'Y',並確保user_id 3和5的bool_field值爲null。

如果用戶不與其他人共享shared_field值,那麼該bool_field應該爲空(如上面的user_id 1和2所示)。

更新:添加了幾行以顯示多個user_id可以共享給定的shared_field(例如,1和6都有'abc'; 3,4和5都有'ghi' - 只有一個' abc'用戶應該具有'Y',並且只有一個'ghi'用戶應該具有'Y'等,而其餘的在他們的bool_field列中具有空;不共享shared_field值的user_id,例如user_ids 2和7,都應該在它們的bool_field列中全部爲空。)清除爲泥,對不對? ;)

此語句的工作原理:

UPDATE my_table 
    SET bool_field = (CASE 
         WHEN user_id = 4 THEN 'Y' 
         ELSE NULL 
         END) 
WHERE shared_field = 'ghi' 
    AND (SELECT COUNT(shared_field) 
      FROM my_table 
     WHERE shared_field = 'ghi') > 1; 

的問題:是有一些方法,我可以做到同樣的事情,而不事先知道shared_field價值?例如(當然這不起作用) - 更新:「當然」意味着我知道這是行不通的,因爲它是不正確的Oracle語法!重點是讓我知道我想要做什麼。

UPDATE my_table 
    SET bool_field = (CASE 
         WHEN user_id = 4 THEN 'Y' 
         ELSE NULL 
         END) 
WHERE shared_field = (SELECT shared_field FROM my_table WHERE user_id = 4) as sharedVal 
    AND (SELECT COUNT(shared_field) 
      FROM my_table 
     WHERE shared_field = sharedVal) > 1; 

更新:這是一個普通的SQL語句 - 我不能使用存儲過程。

+0

您可以使用before update觸發器將shared_field的所有bool_Fields設置爲null,然後讓更新進程。或者把它放到一個事務過程中,然後調用它,第一步是將它們設置爲空,以更新一條記錄。如果問題全部回滾。 – xQbert 2014-10-31 20:30:20

回答

1

第一,而塔如果說某件事情「不起作用」,告訴我們它不起作用通常很有幫助。例如,您發佈的查詢看起來有語法錯誤(as sharedVal無效,因爲您無法爲在SELECT列表中計算的表達式分配別名)。但目前還不清楚「不起作用」是否意味着你得到了語法錯誤(我們可以使用錯誤消息相對容易地進行調試),或者它是否意味着查詢運行但沒有按照你想要的去做(我如果語法錯誤得到糾正,則預期查詢會執行),在這種情況下,知道查詢如何不做你想做的事情會很有幫助。

我希望像

UPDATE my_table a 
    SET bool_field = (CASE WHEN user_id = 4 
          THEN 'Y' 
          ELSE NULL 
         END) 
WHERE shared_field = (SELECT shared_field 
         FROM my_table b 
         WHERE b.user_id = 4) 
    AND EXISTS(SELECT 1 
       FROM my_table c 
       WHERE a.shared_field = c.shared_field 
        AND a.user_id  != c.user_id) 

工作假設user_id是主鍵。

+0

我已更新我的帖子,以表明我知道第二個示例有語法錯誤。我用它來說明我正在嘗試做什麼,並認爲「當然」會通過我知道這一點來提示人們。你的代碼示例看起來應該可以工作。我會在星期一嘗試一下,讓你知道。 – leanne 2014-10-31 22:55:12

+0

是的,這做了我所需要的。 – leanne 2014-11-03 15:01:04

0

這是一段時間,因爲我已經在Oracle工作,因此請確保該查詢返回要更新的記錄列表:

SELECT * 
FROM my_table m 
WHERE EXISTS (SELECT 1 
     FROM my_table 
     WHERE shared_field = m.shared_field 
     HAVING COUNT(shared_field) > 1); 

如果是這樣,那麼這應該工作:

UPDATE my_table 
    SET bool_field = (CASE 
         WHEN user_id = 4 THEN 'Y' 
         ELSE NULL 
         END) 
WHERE EXISTS (SELECT 1 
     FROM my_table 
     WHERE shared_field = m.shared_field 
     HAVING COUNT(shared_field) > 1); 

你也可以試試這個WHERE條款:

WHERE shared_field IN (SELECT shared_field 
     FROM my_table 
     GROUP BY shared_field 
     HAVING COUNT(shared_field) > 1); 
+0

謝謝!我會在星期一嘗試一下,並讓你知道。但是,我沒有看到具體指明user_id 4的shared_field值的任何代碼,而不是指定shared_field值的任何多次出現的代碼? – leanne 2014-10-31 22:57:49

+0

是的,這一個給我所有與其他user_id共享shared_field值的所有user_id記錄 - 不僅僅是那些特別分享user_id 4的shared_field值的用戶列表。不過,謝謝你的迴應!這可以派上用場。 – leanne 2014-11-03 14:59:20

相關問題