2013-08-04 15 views
1

我有一個巨大的選擇,基本上3選擇與2 UNIONs粘在一起。所有選擇列在我的每個選擇內都相同。每個人都有不同的一面是WHERE clausule。在條件相同的情況下(每個條件只有一個條件與其他條件不同),它們都幾乎相同。我的發言是這樣的mysql union選擇1個不同的條件

(SELECT column_name1, column_name2, column_name3, .... 
FROM users 
LEFT JOIN ... 
    ON ... 
LEFT JOIN ... 
(bunch of LEFT JOINS) 
. 
. 
. 
WHERE (SAME CONDITIONS) AND program_id = 3 order by RAND() limit 100) 
UNION 
(SELECT column_name1, column_name2, column_name3, .... 
FROM users 
LEFT JOIN ... 
    ON ... 
LEFT JOIN ... 
(bunch of LEFT JOINS) 
. 
. 
. 
WHERE (SAME CONDITIONS) AND program_id = 2 order by RAND() limit 100) 
(SELECT column_name1, column_name2, column_name3, .... 
FROM users 
LEFT JOIN ... 
    ON ... 
LEFT JOIN ... 
(bunch of LEFT JOINS) 
. 
. 
. 
WHERE (SAME CONDITIONS) AND program_id = 1 order by RAND() limit 100) 

並從這個選擇我也想選擇一些其他數據。我這樣做是因爲我想要有不同的用戶順序,但他們的順序需要始終從最高的程序到最低的程序。問題是我能以某種方式使這個選擇更短嗎?因爲幾乎所有東西都是相同的,但是有一個條件是沒有意義的。當我在那裏發現一個bug或想要改變某些東西(因爲這只是選擇的一部分),我必須重寫所有內容。 你能幫我嗎?

回答

1

您可以嘗試以下操作。它首先按照program_id排序,然後隨機排列。它使用用戶定義的變量對行進行排序,每次到達新的program_id時從1開始。最後,只有在等級低於或等於100

SELECT 
    id, 
    program_id 


FROM(
    SELECT 
    id, 
    program_id, 
    @rank := IF(@program = program_id, @rank + 1, 1) AS rank, 
    @program := program_id 


    FROM(
    SELECT 
     id, 
     program_id 

    FROM users 

    WHERE program_id IN(1, 2, 3) 
     #AND [other conditions] 

    ORDER BY 
     program_id, 
     RAND() 
) AS Derived 

    JOIN (SELECT @program := 0, @rank := 0) AS var 
) AS Derived 


WHERE rank <= 100 

ORDER BY 
    program_id, 
    id DESC 

http://sqlfiddle.com/#!2/92d7b/1

+0

+1的方式返回行。我想你應該添加額外的列(即使用'*'),因爲這是問題的要求。 –