2015-11-03 33 views
0

我有以下MySQL語句,它運行良好。使用MAX函數時從表中獲取字段

SELECT c.id, IFNULL(MAX(l.id), 0) as level_id 
FROM course c 
LEFT JOIN level l ON c.level_id = l.id 
WHERE c.user_id = '123'  
GROUP BY c.id 

一門課程可以有多個級別,因此IFNULL(MAX(l.id), 0)作品選擇最高。

但是,我不想返回最高級別的ID,而是希望獲得名稱。我嘗試了以下,但MySQL不喜歡在select中使用值。

SELECT c.id, IFNULL(MAX(l.id), 0) as level_id, l2.name 
FROM course c 
LEFT JOIN level l ON c.level_id = l.id 
INNER JOIN level l2 ON level_id = l2.id 
WHERE c.user_id = '123'  
GROUP BY c.id 

我簡化了我的提問(爲了便於閱讀),所以希望問題仍然有意義。

+1

第一個查詢應該給你一個錯誤,你有一個JOINs中間的WHERE子句(代碼看起來和你第二次查詢的相同)。 – Kickstart

+1

@Kickstart感謝您的發現,更新了我的問題 – xylar

回答

1

有了這種類型的查詢,我認爲最簡單的方法是substring_index()/group_concat()招:

SELECT c.id, COALESCE(MAX(l.id), 0) as level_id, 
     SUBSTRING_INDEX(GROUP_CONCAT(l2.name ORDER BY l.id DESC), ',', 1) as name 
FROM course c LEFT JOIN 
    level l 
    ON c.level_id = l.id INNER JOIN 
    level l2 
    ON level_id = l2.id 
WHERE c.user_id = '123' 
GROUP BY c.id; 

注意,WHERE在查詢放錯了地方。這種方法

注意事項:

  • 你需要一個不同的分隔符,如果name可能有逗號。
  • 中間結果的長度有一個內部限制。如果這是一個問題,可以增加長度。
+0

我不知道是否需要第二次加入到關卡表(如果存在ID爲0的虛擬關卡)。然而,認爲連接條件將無法抗爭,因爲我認爲這是使用聚合函數的結果的意義(即,應對0的l.id) – Kickstart

1

另一種方法是做一個子查詢的,結果加入背靠等級表來獲得級別名稱: -

SELECT sub0.id, sub0.level_id, l2.name 
FROM 
(
    SELECT c.id, IFNULL(MAX(l.id), 0) as level_id 
    FROM course c 
    LEFT JOIN level l ON c.level_id = l.id 
    WHERE c.user_id = '123' 
    GROUP BY c.id 
) 
LEFT OUTER JOIN level l2 ON l2.id = sub0.level_id