2012-04-09 55 views
2

我需要我的主要查詢與子查詢相結合:梳理這兩個MySQL查詢

當前查詢(工作):

SELECT *,(SELECT SUM(shift_length)FROM overtime_list 
WHERE overtime_list.user_ID = users.user_ID AND overtime_list.date > '$totalovertimedays') AS overtime_total FROM availability_list 
JOIN users ON users.user_ID = availability_list.user_ID 
JOIN stations ON users.station_ID` = stations.station_ID 
WHERE availability_list.date = '$date' AND type = '$type' 
ORDER BY overtime_total ASC 

($日期和$類型都瓦爾填寫通過PHP)

查詢我想插入這個作爲一個子查詢:

SELECT role_ID, GROUP_CONCAT(users_roles.role_ID) AS roles FROM users 
JOIN users_roles ON users.user_ID = users_roles.user_ID 
GROUP BY users.users_ID 

我得到了這麼遠 - 但我不能似乎得到了GROUP BY工作,所以它不正確列出他們:

SELECT *,(SELECT SUM(shift_length)FROM overtime_list 
WHERE overtime_list.user_ID = users.user_ID AND overtime_list.date > '$totalovertimedays') AS overtime_total FROM availability_list 
JOIN users ON users.user_ID = availability_list.user_ID 
JOIN `stations` ON `users`.`station_ID` = `stations`.`station_ID`, 
(SELECT role_ID, GROUP_CONCAT(users_roles.role_ID separator ', ') AS roles FROM users JOIN users_roles ON users.user_ID = users_roles.user_ID GROUP BY users.user_ID) AS roles 
WHERE availability_list.date = '$date' AND type = '$type' 
ORDER BY overtime_total ASC 

availability_list表:

+----------+---------+ 
| user_ID | user | 
+----------+---------+ 
|  1 | Smith | 
+----------+---------+ 
|  2 | Jones | 
+----------+---------+ 
|  3 | Greg | 
+----------+---------+ 

overtime_list表:

+----------+----------------+------------+ 
| date | shift_length | user_ID | 
+----------+----------------+------------+ 
| 1/1/11 | 5   |  1  | 
+----------+---------+------+------------+ 
| 1/2/11 | 5   |  2  | 
+----------+---------+------+------------+ 
| 1/6/11 | 2   |  2  | 
+----------+---------+------+------------+ 
| 1/8/11 | 5   |  1  | 
+----------+---------+------+------------+ 
| 1/12/11 | 2   |  1  | 
+----------+---------+------+------------+ 

users_roles表:

+----------+---------+ 
| user_ID | roles | 
+----------+---------+ 
|  1 | Admin | 
+----------+---------+ 
|  2 | Staff | 
+----------+---------+ 
|  2 | Admin | 
+----------+---------+ 
|  2 | Super | 
+----------+---------+ 
|  1 | Other | 
+----------+---------+ 

那麼結果將是:

+----------+---------+----------------------------+------------------+ 
| user_ID | user | roles     | overtime_total | 
+----------+---------+----------------------------+------------------+ 
|  1 | Smith | Admin, Other   |  12  | 
+----------+---------+----------------------------+------------------+ 
|  2 | Jones | Staff, Admin, Super  |  7   | 
+----------+---------+----------------------------+------------------+ 
|  3 | Greg |       | null (or zero) | 
+----------+---------+----------------------------+------------------+ 
+2

當提問這樣的問題時,通常是一個好主意,包括一個例子的形式 - 給出這個數據,我想檢索以下結果。你提出問題越多,答案就越好。 – nnichols 2012-04-09 11:07:44

+0

好的 - 謝謝nnichols - 下次會這麼做 – Laurence 2012-04-09 11:58:45

+0

在同一天的同一個用戶,在同一用戶的overtime_list中是否會有多個條目?我認爲我的查詢將導致來自users_roles和overtime_list的兩個子集的笛卡爾積。 – nnichols 2012-04-09 12:04:07

回答

2

這應該工作 -

SELECT users.*, 
    SUM(overtime_list.shift_length) AS overtime_total, 
    (SELECT GROUP_CONCAT(users_roles.role_ID) FROM users_roles WHERE users.user_ID = users_roles.user_ID) AS roles 
FROM availability_list 
INNER JOIN users 
    ON users.user_ID = availability_list.user_ID 
INNER JOIN `stations` 
    ON `users`.`station_ID` = `stations`.`station_ID` 
INNER JOIN overtime_list 
    ON overtime_list.user_ID = users.user_ID 
    AND overtime_list.date >= '$totalovertimedays' 
WHERE availability_list.date = '$date' 
AND type = '$type' 
GROUP BY users.user_ID 
ORDER BY overtime_total ASC 
+0

完美 - 謝謝 - 這個作品! – Laurence 2012-04-09 15:48:22

+0

哦不 - 這是一個錯誤!用我的查詢,如果沒有記錄(overtime_list.date> ='totalovertimedays')返回,總計數爲0,但用戶仍然顯示。但是在你的回答中,如果沒有記錄(overtime_list.date> ='totalovertimedays'),那麼用戶根本不顯示! – Laurence 2012-04-11 05:01:18

+0

我編輯了我原來的問題,以顯示用戶沒有加班記錄澄清 – Laurence 2012-04-11 05:03:59

0

我建議重新思考的結果你要。你問這個:

+----------+---------+----------------------------+------------------+ 
| user_ID | user | roles     | overtime_total | 
+----------+---------+----------------------------+------------------+ 
|  1 | Smith | Admin, Other   |  12  | 
+----------+---------+----------------------------+------------------+ 
|  2 | Jones | Staff, Admin, Super  |  7   | 
+----------+---------+----------------------------+------------------+ 

然而,這是更常見的查詢返回此:

+----------+---------+----------------------------+------------------+ 
| user_ID | user | roles     | overtime_total | 
+----------+---------+----------------------------+------------------+ 
|  1 | Smith | Admin     |  12  | 
+----------+---------+----------------------------+------------------+ 
|  1 | Smith | Other     |  12  | 
+----------+---------+----------------------------+------------------+ 
|  2 | Jones | Staff     |  7   | 
+----------+---------+----------------------------+------------------+ 
|  2 | Jones | Admin     |  7   | 
+----------+---------+----------------------------+------------------+ 
|  2 | Jones | Super     |  7   | 
+----------+---------+----------------------------+------------------+ 

它則相當簡單收集在一起,爲每個用戶創建的行,從而收集他們所有的角色。 (你可能會覺得它更容易,如果你第一次排序user_ID,並檢測USER_ID變化時)

+0

謝謝Scraimer - 我需要將它們分組以用於特定報告。 – Laurence 2012-04-09 15:40:50

0

如果您堅持使用GROUP_CONCAT到組中的所有角色名字連在一起,這可能工作:

SELECT users.user_ID, users.user, 
    (SELECT GROUP_CONCAT(users_roles.roles) 
     FROM users_roles 
     WHERE users_roles.user_ID = users.user_ID) as roles, 
    (SELECT SUM(shift_length) 
     FROM overtime_list 
     WHERE overtime_list.user_ID = users.user_ID 
     AND overtime_list.date > '$totalovertimedays') AS overtime_total, 
    FROM availability_list 
    JOIN users ON users.user_ID = availability_list.user_ID 
    JOIN stations ON users.station_ID` = stations.station_ID 
    WHERE availability_list.date = '$date' AND type = '$type' 
    ORDER BY overtime_total ASC 

使用這個第二個子查詢似乎使這個查詢效率比現在低,所以我很謹慎在高容量系統中使用它。如果你每天只讀幾次幾千條,你永遠不會注意到延遲。