2015-02-07 78 views
0

我希望它不會被標記爲脫離主題,因爲,是的 - 我要求對所述問題採用「最佳」方法。MySQLi,多列高分,高效查詢,正確的方法

比方說,我們已經得到了高分表列app_idbest_scorebest_timemost_dropslongest_something和夫婦更多。 我想收集app_id分組的前三個結果ON EACH CATEGORY?

現在我在循環中使用的每個類別分別排名查詢:

SELECT app_id, best_something1, 
FIND_IN_SET(best_something1, 
(SELECT GROUP_CONCAT(best_something1 
ORDER BY best_something1 DESC) 
FROM highscores)) AS rank 
FROM highscores 
ORDER BY best_something1 DESC LIMIT 3; 

有兩件事情值得補充:

  1. 特定應用中的所有列正在以相同的更新時間(可以考慮創建一個幫助表)。
  2. 預期的「turbo查詢」的結果可能會經常被要求 - 就像更新值一樣。

我對SQL很基本,懷疑它有更多的命令組合在一起可以做到這一點?

我期望從這篇文章中得知,一些聰明的貓頭鷹至少會指出去哪裏或如何去的方向。

編輯---確定,提供樣品表: http://sqlfiddle.com/#!2/eef053/1

編輯---好吧,這裏是樣品的結果太(已JSON格式,SRY):

{「total_blocks 「:[[」 13" , 「174」, 「1」],[ 「9」, 「153」, 「2」],[ 「10」, 「26」, 「3」]], 「total_games」: [[ 「13」, 「15」, 「1」],[ 「9」, 「12」, 「2」],[ 「10」, 「2」, 「3」]], 「total_score」:[[ 「13」, 「410」, 「1」],[ 「9」, 「332」, 「2」],[ 「11」, 「88」, 「3」]], 「aver_pps」:[[「11 」, 「4.34011」, 「1」],[ 「13」, 「2.64521」, 「2」],[ 「12」, 「2.60623」, 「3」]], 「aver_drop_per_game」:[[ 「11」, 「20」, 「1」],[ 「10」, 「13」, 「2」],[ 「9」, 「12.75」, 「3」]], 「aver_drop_val」:[[ 「11」,「4.4 」, 「1」],[ 「13」, 「2.35632」, 「2」],[ 「9」, 「2.16993」, 「3」]] 「aver_score」:[[ 「11」, 「88」, 「1」],[ 「9」, 「27.6667」, 「2」],[ 「13」,「27.3333 」, 「3」]] 「best_pps」:[[ 「13」, 「4.9527」, 「1」],[ 「11」, 「4.34011」, 「2」],[ 「9」, 「4.13076」, 「3」]], 「most_drops」:[[ 「11」, 「20」, 「1」],[ 「9」, 「16」, 「2」],[ 「13」, 「16」,「2 「]]」 longest_drop 「:[[」 9" , 「3」, 「1」],[ 「13」, 「2」, 「2」],[ 「11」, 「2」, 「2」] ], 「best_drop」:[[ 「11」, 「42」, 「1」],[ 「13」, 「36」, 「2」],[ 「9」, 「30」, 「3」]], 「best_score」:[[「11」,「88」,「1」],[「13」,「78」,「2」],[「9」,「58」,「3」]]}

+2

如果您提供了示例表格(當然是表格格式)和您想要的輸出示例,那麼您的問題就會更加「清晰」。 – belwood 2015-02-07 03:25:39

+0

什麼是'app'?這是另一張桌子嗎? – 2015-02-07 03:27:44

+0

http://sqlfiddle.com/ – EL3PHANTEN 2015-02-07 03:31:04

回答

2

當我遇到這種情況時,我更願意使用UNION子句,並將針對每個ORDERing和LIMIT定製的查詢進行組合。

http://dev.mysql.com/doc/refman/5.1/en/union.html

UNION結合結果行垂直(上3行5個分類類別產生15行)。

爲了您的特定目的,您可以將它們作爲子SELECT選擇,將它們用GROUP_CONCAT分組,然後在用戶上進行分組,以便每個分區都有分隔列表。

+0

!這是事情!似乎是一個非常好的解決方案。讓我先測試一下,並確認所有其他需求,但我從第一個閃光點就愛上了它! – axldns 2015-02-07 04:20:05

+0

我還應該提到,如果您的應用程序不介意將其作爲2D結果集,那麼只需在不使用GROUP_CONCAT的情況下進行旋轉就非常理想。我很快就會用這種方法給你另一個答案。 – 2015-02-07 04:40:21

+0

哎呀,我的意思是說沒有pivoting ...沒有GROUP_CONCAT(我迷惑自己)...數據的3個維度...但輸出與用戶直接行。現在我正在創作答案。 – 2015-02-07 04:47:40

1

我會測試類似此查詢的內容,以查看性能是否更好。我覺得這涉及相當接近滿足規格:

(SELECT 99 AS seq_ 
     , a.category 
     , CONVERT(a.val,DOUBLE) AS val 
     , FIND_IN_SET(a.val,r.highest_vals) AS rank 
     , a.user_id 
    FROM (SELECT 'total_blocks' AS category 
       , b.`total_blocks` AS val 
       , b.user_id 
       FROM app b 
      ORDER BY b.`total_blocks` DESC 
      LIMIT 3 
     ) a 
    CROSS 
    JOIN (SELECT GROUP_CONCAT(s.val ORDER BY s.val DESC) AS highest_vals 
       FROM (SELECT t.`total_blocks` AS val 
         FROM app t 
         ORDER BY t.`total_blocks` DESC 
         LIMIT 3 
        ) s 
     ) r 
    ORDER BY a.val DESC 
) 
UNION ALL 
(SELECT 97 AS seq_ 
     , a.category 
     , CONVERT(a.val,DOUBLE) AS val 
     , FIND_IN_SET(a.val,r.highest_vals) AS rank 
     , a.user_id 
    FROM (SELECT 'XXX' AS category 
       , b.`XXX` AS val 
       , b.user_id 
       FROM app b 
      ORDER BY b.`XXX` DESC 
      LIMIT 3 
     ) a 
    CROSS 
    JOIN (SELECT GROUP_CONCAT(s.val ORDER BY s.val DESC) AS highest_vals 
       FROM (SELECT t.`XXX` AS val 
         FROM app t 
         ORDER BY t.`XXX` DESC 
         LIMIT 3 
        ) s 
     ) r 
    ORDER BY a.val DESC 
) 
ORDER BY seq_ DESC, val DESC 

要解開這個有點......這是結合UNION ALL一套運營商基本上是單獨的查詢。

每個查詢都會返回一個字面值以允許排序。 (在這種情況下,我給出了一個相當匿名的名字列seq_(sequence)...如果特定的順序不重要,那麼這個可以被移除

每個查詢還返回一個文字值告訴哪個「類別」行爲

因爲返回的一些值是INTEGER,而其他的是FLOAT,所以我會將所有這些值都轉換爲浮點數,因此每個查詢的數據類型都是一致的

對於FLOAT(浮點)類型的值,可能存在比較問題,所以我會將它們轉換爲十進制並將它們串聯在一起,使用GROUP_CONCAT(作爲原始查詢確實)。

由於我們僅從每個查詢返回三行,因此我們只需將三個最大值連接在一起。 (如果首先有雙向「領帶」,我們將返回排名值1,1,3。)

每個查詢的適當索引將提高大集合的性能。

... ON app (total_blocks, user_id) 
... ON app (best_pps,user_id) 
... ON app (XXX,user_id) 
+0

哇,這也是全面的解決方法,謝謝!我喜歡命名最終輸出列的概念。好的地方浮動和整數了。肯定會給你一個去。然而,現在它正在寫下一個存儲過程,它可能會表現得最好,並且更容易實現其他「馬戲團需求任務」。再一次感謝你所做的切片。這是教學! – axldns 2015-02-08 01:45:00