2010-08-28 20 views
0

這篇文章很遺憾,但問題也很複雜。mysql根據條件切換到備用表

使用MySQL和PHP,
我可以解決我的問題有3個SQL請求,但沒有1例,也不在2

所以這就是爲什麼我張貼在這裏:
沒有任何的你知道一種方法在少於三招的情況下做到這一點?

(對不起,我的英語)

首先讓我解釋的背景:
它是關於主題公園!

所以有主題公園業主
和他擁有一個不同區域的主題公園,每個區域包含遊戲。
根據遊戲經理(負責遊戲的人),每個遊戲都可以設置不同的設置。

下面是模式的有趣的部分是什麼樣子
有5桌

themeparkzone
--name(VARCHAR)

themeparkzone_has_game_with_manager
--themeparkzone_id(PK)
- -game_id(pk)
--manager_id(fk)
--game_settings(text)

themeparkzone_has_game
--themeparkzone_id(PK)
--game_id(PK)
--game_settings(文本)

遊戲
--name(VARCHAR)

經理
- 名稱(varchar)

兩個表格可能需要更多解釋:

themeparkzone_has_game_with_manager and themeparkzone_has_game。

如果主題樂園所有者 寫道他們,themeparkzone_has_game可能會保留遊戲的默認設置。

然後themeparkzone_has_game_with_manager認爲,game_manager有遊戲設置(或還沒有)的設置,
並設置時,這些設置應該從themeparkzone_has_game表覆蓋默認設置。

因爲主題公園主人希望他的主題公園是非常有吸引力的,他計劃每天更改設置,
這裏是他和他的團隊將要處理的約定:

決定哪些遊戲設置將適用,

我們下面瓦爾在啓動中給定:
- 的MANAGER_ID:例如22
- 在themeparkzone IDS今天,例如12,13,14

所以最終的目標是:
對於給定的經理標識,而對於給定的themeparkzone_ids,
找出名稱和遊戲的設置,

因爲:
如果設置在themeparkzone_has_game_with_manager設置它將應用
其他
如果設置在themeparkzone_has_game設置將適用
其他
沒有遊戲。

這是我有問題,
因爲我could'nt 1個請求中做到這一點,
我花了第一個請求循環的themeparkzone_ids,
讓現在的問題是要找到遊戲的名稱,給定manager_id和給定themeparkzone_id的設置。

在這一點上,我可以在兩個請求中做到這一點,但我想知道是否可以在一個請求中做到這一點。

我的要求是:

SELECT g.name,w.game_settings
從博弈摹
INNER JOIN themeparkzone_has_game_with_manager W於w.game_id = g.id
WHERE w.manager_id = 22
AND w.themeparkzone_id在(12,13,14)

SELECT g.name,h.game_settings
FROM遊戲克
INNER JOIN themeparkzone_has_game H於h.game_id = g.id
WHERE h.themeparkzone_id中(12,13,14)

其中FOREACH,我把所得到的陣列中的PHP數組和然後根據慣例將它們混合 。

所以我想知道是否有一種方法可以解決mysql請求 中的條件,而不是使用php來完成。

會做這樣的事情的請求:
的foreach(themeparkzone_id和經理標識)
如果存在匹配的themeparkzone_has_game_with_manager
takeit設置,
否則
如果存在匹配的themeparkzone_has_game
takeit設置,
其他
服裝。

希望有人能夠理解我試圖解釋的內容。

+1

是否有真正令人信服的理由在mySQL而不是PHP中執行此操作?你有任何性能問題?我很難想象這是值得嘗試進入mySQL的努力 - 使它成爲一個查詢條件,不管表是否存在與我的mySQL精神不同步。 – 2010-08-28 10:59:05

回答

2

考慮到你的數據庫佈局,我認爲改變一些東西可能會更好。

我會把themeparkzone_has_game_with_managerthemeparkzone_has_game_with_manager放在一張表中。然後,我將創建一個新表games_managers,該表建立了管理員可以管理哪些遊戲的連接。

然後我認爲,應該可以用更少的請求來做到這一點。

注意,你必須工作的細節爲自己,也就是說,如果它需要有一個經理或可能不是你每場比賽的指定標誌等

+0

我同意這一點(儘管我認爲你的意思是引用不同的表名,所以你可能想編輯你的答案)。有一個表格,其中有一個額外的布爾型字段,指定是否由經理設置。 – Nick 2010-08-28 11:08:50

+1

@Nick如果我們設置布爾字段,這是由管理員指定,那麼該遊戲的默認設置將丟失。 – 2010-08-28 12:00:10

+0

是的,如果我改變你說的結構, 默認設置丟失,這就是問題所在! 如何在一個請求中獲取可能包含覆蓋設置的表,但如果未找到記錄嘗試從默認設置表中獲取設置 ? – ling 2010-08-28 12:39:15

0

你可以做到這一點使用LEFT JOINCOALESCE

SELECT 
    g.name, 
    COALESCE(w.game_settings, h.game_settings) 
FROM 
    game AS g 
    INNER JOIN themeparkzone_has_game AS h ON h.game_id = g.id 
    LEFT JOIN themeparkzone_has_game_with_manager AS w ON 
     w.game_id = g.id AND 
     w.themeparkzone_id = h.themeparkzone_id AND 
     w.manager_id = 22 
WHERE 
    h.themeparkzone_id IN (12, 13, 14) 

不像INNER JOIN,一個LEFT JOIN總是包含在左側表中的每一行的至少一排,即使有在右邊的表中沒有行匹配的連接條件。在這種情況下,右表中的列將全部爲NULLCOALESCE()返回所提供的第一個非NULL值,因此如果themeparkzone_has_game_with_manager中沒有匹配的行,它將返回的值從themeparkzone_has_game

+0

它沒有按預期工作(得到一個空的結果), 但我要解決這些內部聯接,左聯接和合並的東西,這聽起來不錯。感謝名單。 – ling 2010-08-28 14:28:32

0

萬歲,
我終於找到了一個轉身,
這對像我這樣的新手有點混亂,但它的工作原理,並...
只有結果事...

這裏是對應於該請求我的需求:
感謝名單都對你有所幫助:

選擇
COALESCE(g.name,g2.name),
聚結(w.params,h.params)
FROM
themeparkzoneŽ
LEFT JOIN themeparkzone_has_game_with_manager瓦特ON w.themeparkzone_id = z.id AND w.manager_id = 2
LEFT JOIN上themeparkzone_has_gameħh.themeparkzone_id = Z .id
LEFT JOIN遊戲g關於g.id = w.game_id
左連接遊戲g2打開g2.id = h.game_id 其中z。身份證件(12,13,14)

所以這個要求取回導致themeparkzone_has_game_with_manager表, 如果不成立,嘗試獲取來自themeparkzone_has_game 結果,如果沒有任何成立後,仍返回空結果。
希望它可以幫助別人。

+0

oups,最後它失敗了! 現在放棄,在3個查詢中做... – ling 2010-08-30 08:59:12