2011-07-13 23 views
3

我想對newtable的同步商店IDS從maintable這裏的ID:如果「子查詢返回多個1行」考慮NULL

UPDATE newtable t SET t.store_id = (SELECT store_id FROM maintable s 
WHERE t.state = s.state AND s.city = t.city AND t.name = s.name) 

每當一個子查詢返回多行它的錯誤「子查詢返回多於一行」,但當它返回零行時,子查詢被認爲沒有返回任何內容,因此newtable上的store_id保持爲NULL。這裏沒有新東西,它只是它的工作原理。

我想知道是否有可能讓子查詢輸出相同,當它有沒有匹配,當它有多個匹配的行。

這樣我就可以將store_id只同步到主表上的一個匹配行,並在子查詢中出現多個匹配行時跳過。

+0

如果'SELECT store_id'產生一個值,則將't.store_id'設置爲該值;如果它什麼都不產生,那麼將't.store_id'設置爲NULL;如果它產生多個值,則將't.store_id'設置爲NULL。對? –

+0

@mu太短:我認爲當返回多個值時,他只想丟棄重複的值並將其中一個存儲在'store_id'中,並且當沒有返回值時,他想要存儲默認值。 –

+0

@Sayem:這是我不清楚的,這個問題的最後兩段似乎是在說不同的事情。 –

回答

6

我想你可能會尋找一個HAVING子句強制查詢到恰好一次匹配:

UPDATE newtable t 
SET t.store_id = (
    SELECT store_id 
    FROM maintable s 
    WHERE t.state = s.state 
     AND s.city = t.city 
     AND t.name = s.name 
    HAVING COUNT(*) = 1 
) 

這應該使多個匹配的行爲與沒有匹配相同。 HAVING子句幾乎應用於查詢過程的最後;如果沒有來自WHERE或多於一個匹配的匹配,那麼COUNT(*) = 1將失敗,並且內部查詢將不返回任何內容,但如果只有一行,則COUNT(*) = 1將成功,並且內部查詢將返回該單個匹配。

0

您可能會考慮在您的子查詢中加入LIMIT 1,以根據您的特定需求更好地實現您正在嘗試完成的任務。

否則,你應該能夠發揮創意與IF或CASE:

UPDATE newtable t SET t.store_id = (
    SELECT IF(num>1, NULL, storeid) FROM (
     SELECT COUNT(*) AS num, storeid FROM maintable s WHERE t.state=s.state AND s.city=t.city AND t.name=s.name 
    ) 
) 

未經檢驗的,但應該讓你在球場。

+0

LIMIT 1不是一個選項,因爲它不會是一個確切的store_id匹配。我會玩IF,CASE並讓你知道。 –

0
UPDATE newtable t SET t.store_id = IFNULL((SELECT store_id FROM maintable s 
WHERE t.state = s.state AND s.city = t.city AND t.name = s.name HAVING COUNT(*) = 1), t.store_id) 

IFNULL(use_this_value_if_not_null,value_if_first_isnull)

+0

否...#1242 - 子查詢返回多於一行 –

+0

我已經添加了HAVING COUNT(*)= 1,就像「@mu太短」一樣,只是爲了獲得完整的解決方案,因爲我不確定是否@mu答案在內部查詢返回null時用於你想要的內容。 – Seeker