2009-12-31 32 views
1

希望這種格式更好......感謝OMG小馬,彼得·朗和他的耐心回答我的第一次嘗試。在複雜查詢中定義mysql中的視圖 - 嘗試#2

我正在設置一個遊戲,每個用戶每週選擇一個選手,有點像挑選你認爲會贏的球隊。我需要創建一個視圖,對於USER,CONTESTANT和WEEK的每個組合,該用戶在整個星期內累積選擇該特定CONTESTANT的次數。數據表是這樣的:

Data table "contestants" 
contestant name 
11   Aaron 
12    Bob 
13   Catherine 
14   David 

Data table "picks" 
user week contestant 
1001 1  11 
1001 2  11 
1002 1  12 
1002 2  13 

現在,我已經得到了工作,給我我想要的精確輸出代碼,但問題是,我不能讓一個觀點出來的,因爲有是子查詢。這裏是代碼和正確的輸出:

SELECT user, contestant ,week, count(valid_pick) num_picks 
    FROM 
    (
    SELECT DISTINCT p.user , c.contestant, p.week 
    FROM contestants c , picks p 
    ORDER BY user , contestant , week 
) t1 
    LEFT JOIN 
    (
    SELECT user p_user , contestant p_contestant , week p_week , 
     1 as valid_pick 
    FROM picks p 
    ORDER BY p.user , p_contestant , p_week 
) t2 
    ON t1.user = t2.p_user AND t1.contestant = t2.p_contestant 
    AND t2.p_week <= t1.week 
GROUP BY user , contestant , week 

user contestant week num_picks 
1001 11 1 1 
1001 11 2 2 
1001 12 1 0 
1001 12 2 0 
1001 13 1 0 
1001 13 2 0 
1001 14 1 0 
1001 14 2 0 
1002 11 1 0 
1002 11 2 0 
1002 12 1 1 
1002 12 2 1 
1002 13 1 0 
1002 13 2 1 
1002 14 1 0 
1002 14 2 0 

這有0是在正確的地方,並正確計算按周積累的選秀權。

但我真的需要這個視圖,所以我想創建子查詢作爲迷你視圖。下面是代碼:

CREATE OR REPLACE VIEW miniview1 AS 
    SELECT DISTINCT p.user , c.contestant, p.week 
    FROM contestants c , picks p 
    ORDER BY user , contestant , week 
; 
CREATE OR REPLACE VIEW miniview2 AS 
    SELECT user p_user , contestant p_contestant , week p_week , 
     1 as valid_pick 
    FROM picks p 
    ORDER BY p.user , p_contestant , p_week 
; 
CREATE OR REPLACE VIEW myview AS 
SELECT user, contestant ,week, count(valid_pick) num_picks 
    FROM miniview1 t1 
    LEFT JOIN miniview2 t2 
    ON t1.user = t2.p_user AND t1.contestant = t2.p_contestant 
    AND t2.p_week <= t1.week 
GROUP BY user , contestant , week 

但我得到 「MyView的」 是這樣的:

user contestant week num_picks 
1001 14 1 1 
1002 14 1 1 
1001 14 2 1 
1002 14 2 1 
1002 11 1 1 
1002 11 2 1 
1001 12 1 1 
1001 12 2 1 
1001 13 1 1 
1002 13 1 1 
1001 13 2 1 
1001 11 1 1 
1001 11 2 2 
1002 12 1 1 
1002 12 2 1 
1002 13 2 1 

這顯然是錯誤的。這看起來像是一個簡單的替代品。我檢查了miniview1和miniview2,它們是完全正確的。有什麼想法發生在這裏?

謝謝,並感謝您對mysql(和stackoverflow)新手的耐心等待!

doxguy

回答

0

miniview1:

 
CREATE OR REPLACE VIEW miniview1 AS 
    SELECT p.user , c.contestant, p.week 
    FROM contestants c , picks p 
    GROUP BY user , contestant , week; 

miniview2:

 
    SELECT user p_user , contestant p_contestant , week p_week , 
    1 as valid_pick 
    FROM picks p; 

現在可以嘗試選擇在使用miniview1和miniview2

SELECT user, contestant ,week, count(valid_pick) num_picks 
    FROM 
    ( SELECT * from miniview1) t1 
    LEFT JOIN 
    ( SELECT * from miniview2) t2 
ON t1.user = t2.p_user AND t1.contestant = t2.p_contestant 
AND t2.p_week <= t1.week 
GROUP BY user , contestant , week; 

這同樣可以產生正確的結果在你的例子中。所以看起來這是myview的問題,而不是miniview1或miniview2。

我認爲這是因爲你不能將上面的SELECT作爲VIEW來編寫。 SELECT使用子查詢,而VIEW不能使用子查詢。

換句話說:上面的SELECT語句與VIEW myview沒有相同的語義。

+0

謝謝。這是我試圖理解的迷你觀點的難題。 – doxguy 2010-01-09 05:49:34

0

我想你想是這樣的:

Data table "contestants" 
contestant name 
11   Aaron 
12    Bob 
13   Catherine 
14   David 

Data table "weeks" 
contestant week 
11   1 
11   2 
12   1 
12   2 

Data table "user" 
user  name 
1001  Fred 
1002  Jane 

Data table "picks" 
user week contestant 
1001 1  11 
1001 2  11 
1002 1  12 
1002 2  13 

select p.user, w.contestant, w.week, 
    (select count(*) 
     from picks p 
     where p.week = w.week 
     and p.contestant = w.contestant) 
from user u 
join weeks w 
join contestants c on c.contestant = w.contestant 

請注意,此代碼是未經測試。

爲了清楚起見,我已經將名稱縮短並且數據庫已經過時。實施可以整理一下。

+0

感謝您的回答。我的問題(作爲一個完整的mysql新手)真的想了解mysql的操作。爲什麼當我將子查詢寫成視圖然後插入視圖時,會得到不同的結果? 感謝您的回答。 – doxguy 2010-01-09 05:49:01

0

doxguy,你寫道:

...我檢查miniview1和miniview2和他們是完全正確的...

什麼,你會期望從miniview1一個正確的結果?

當我想你的miniview1的定義,然後我得到的結果,這是非常明顯的錯誤對我說:

 
select * from miniview1 
user contestant week 
1001 11   1 
... 
1002 13   1 
1002 13   2 
1002 14   1 
1002 14   2 

而是 - 例如 - 有一個與選手中排名第14,在所有的較量。

編輯:我知道這不能回答你的問題。這僅僅是我發現的奇怪之處。

+0

我得到你所得到的,如果我運行子查詢而不是將它寫入到miniview1,那我也會得到同樣的結果。沒有人選擇參賽選手14,這是事實,但我希望參賽選手14在每場比賽的決賽桌中都有一個0,這就是我的設置。也許有更好的方法來做到這一點(事實上我現在用另一種方式完成任務),但正如你所看到的,我只想了解爲什麼將這個子查詢寫入視圖然後使用視圖給出的答案不僅僅是直接使用子查詢。感謝您花時間回答。 – doxguy 2010-01-12 01:42:13