2017-04-13 89 views
-3

我有一個表格,結構如下。 該表主要記錄性別= 1的地方。MySQL獲得加權結果

我正在尋找一個解決方案來獲得結果集,其中60%的記錄頂部有性別= 1,40%與性別= 2混合,有序通過人氣desc。 性別= 2的成員數量少得多,這意味着結果集應該只有性別= 1的記錄。

會員表

id | nickname | gender | popularity 
1 | jake  | 1  | 80 
2 | mike  | 1  | 88 
3 | dave  | 1  | 75 
4 | jenny | 2  | 85 
5 | peter | 1  | 83 
6 | nina  | 2  | 88 
7 | mister | 1  | 77 
8 | drake | 1  | 80 

結果應該是這樣的,它必須滿足不了確切加權列表。目標是看到兩性的混合結果。

id | nickname | gender | popularity 
2 | mike  | 1  | 88 
5 | peter | 1  | 83 
6 | nina  | 2  | 88 
1 | jake  | 1  | 80 
8 | drake | 1  | 80 
4 | jenny | 2  | 85 
7 | mister | 1  | 77 
3 | dave  | 1  | 75 

我到目前爲止的最好成績是(它不照顧有關40:60分):

SET @rank=0; 
SET @rank2=0; 
SELECT * FROM (
SELECT @rank:[email protected]+1 AS rank, q.* FROM (SELECT * FROM test WHERE gender = 1  ORDER BY popularity DESC) AS q 
UNION 
SELECT @rank2:[email protected]+1 AS rank, q.* FROM (SELECT * FROM test WHERE gender = 2 ORDER BY popularity DESC) AS q 
) AS r ORDER BY rank; 
+1

這是一個需求規格說明,而不是一個問題。請提出問題,並分享您的嘗試。 – Shadow

+0

爲了澄清,您要求我們提供一個列表,其中最多40%的條目是「性別= 2」,其餘是「性別= 1」?或者你是否要求我們製作一份僅按照受歡迎程度排序的列表,如果您期望沒有返回「性別= 2」條目,儘管它可能在理論上是可能的? – toonice

+0

@toonice是的我要求提供一個列表,顯示40%的條目,其中性別= 2,其餘爲性別= 1 – nenad007

回答

0

請嘗試...

SET @gender1Count = SELECT COUNT(*) 
        FROM tblMember 
        WHERE gender = 1; 

SET @gender2Count = SELECT COUNT(*) 
        FROM tblMember 
        WHERE gender = 2; 

SET @totalCount = SELECT COUNT(*) 
        FROM tblMember; 

SELECT id AS id, 
     nickname AS nickname, 
     gender AS gender, 
     popularity AS popularity 
FROM tblMember 
JOIN (SELECT id AS id 
     FROM tblMember 
     WHERE gender = 1 
     ORDER BY popularity DESC 
     LIMIT CASE 
      WHEN @gender1Count > @totalCount * 3/5 
       ROUND(@gender2Count * 3/2) 
      ELSE 
       @gender1Count 
      END 
     UNION 
     SELECT id AS id 
     FROM tblMember 
     WHERE gender = 2 
     ORDER BY popularity DESC 
     LIMIT CASE 
      WHEN @gender1Count > @totalCount * 3/5 
       @gender2Count 
      ELSE 
       ROUND(@gender1Count * 2/3) 
      END 
    ) nominees ON tblMember.id = nominees.id 
ORDER BY popularity DESC; 

上面會給你一個列表,其中60%的條目是gender = 1和40%是gender = 2。請注意,這與gender = 1餘額gender = 2(或佔總列表的40%或更多的gender = 2和餘額gender = 1)的總列表的60%或更多不同。

它通過形成一個列表,其中gender等於1並將其按照popularity的降序排序。然後它通過檢查gender = 1成員的數量是否超過列表的60%(3/5)來確定它將使用LIMIT從該列表中獲取的最多條目的數量。如果確實如此,那麼我們將需要將要檢索的gender = 1記錄的數量減少到gender = 2成員的計數的3/2倍。然後返回所選記錄的id

(對於那些分數不高的人來說,速度很快,40%與2/5(五分之二)相同。如果gender = 2有五分之二的最終名單,那麼gender = 1必須有另外五分之三3/5)爲了找到列表的3/5的大小,我們從已知的2/5(計數爲gender = 2)開始,並將其除以2,以便我們知道列表的1/5的大小。然後可以將此1/5乘以3以確定有多少記錄將構成我們列表的3/5(60%)。)

類似的邏輯用於形成要包括在最終的成員列表中的gender = 2成員名單。

(請注意,每個列表末尾的記錄可能具有與其性別對應於每個列表的最受歡迎的排除的成員相同的流行值,如果沒有任何子列表形成兩個列表那些或未選擇將是任意的(並且基本上半隨機)的選擇。)

的兩個列表然後使用在什麼是簡單類型的垂直加入UNION操作者接合。 (注:比較熟悉的INNER JOIN,LEFT JOIN等,均爲橫向連接)。

然後在我們的原始表格中對我們的id合併列表執行內部JOIN,給我們我們的60%/ 40%列表。最後,這個清單按照popularity的降序排列。

如果您有任何問題或意見,請隨時發佈相應評論。

+0

代碼略有更新。 – toonice

+0

謝謝,在修正了第一個錯誤之後,必須在SET(SELECT COUNT(*)FROM test WHERE gender = 1)中使用括號。我仍在搜索什麼導致語法錯誤與indind LIMIT和CASE有關,我已經添加THEN但仍然沒有加工。 – nenad007