2012-04-10 122 views
2

此查詢產生正確的答案:結合這兩個MySQL查詢

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 availability_list.type = '$type' 
    GROUP BY users.user_ID 
    ORDER BY overtime_total ASC 

輸出:

+----------+---------+----------------------------+------------------+ 
| user_ID | user | roles     | overtime_total | 
+----------+---------+----------------------------+------------------+ 
|  1 | Smith | 1,2      |  12  | 
+----------+---------+----------------------------+------------------+ 
|  2 | Jones | 1,2,3     |  7   | 
+----------+---------+----------------------------+------------------+ 

這是所期望的結果:

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

這是我可以使用的連接,它似乎允許group_concat更正連接「admin,staff,other」 - 但我無法解決如何將它合併到上面的主查詢中?

SELECT users.user_id, GROUP_CONCAT(roles.short_name separator ', ') roles 
FROM users 
JOIN users_roles ON users.user_ID = users_roles.user_ID 
JOIN roles ON users_roles.role_ID= users_roles.role_ID 
GROUP BY users.user_ID 

的users_roles表:

+----------+---------+ 
| user_ID | role_ID | 
+----------+---------+ 
|  1 | 1  | 
+----------+---------+ 
|  2 | 1  | 
+----------+---------+ 
|  2 | 2  | 
+----------+---------+ 
|  2 | 3  | 
+----------+---------+ 
|  1 | 3  | 
+----------+---------+ 

角色表:

+----------+------------+ 
| role_ID | short_name | 
+----------+------------+ 
|  1 | Admin | 
+----------+------------+ 
|  2 | Super | 
+----------+------------+ 
|  3 | Other | 
+----------+------------+ 

回答

2

你可以嘗試:

SELECT users.*, 
     SUM(overtime_list.shift_length) AS overtime_total, 
     (SELECT GROUP_CONCAT(roles.short_name) FROM users_roles 
     INNER JOIN roles ON user_roles.role_ID = roles.role_ID 
     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 availability_list.type = '$type' 
    GROUP BY users.user_ID 
    ORDER BY overtime_total ASC 
+0

嗨馬可 - 它不工作? 「on子句'」中的未知列'user_roles.role_ID'?上面的答案「確實有效」,但由於某種原因,這確實很慢 - 我試圖讓你的工作... – Laurence 2012-04-10 11:02:47

+1

@Laurencei將其更改爲users_roles.role_id。 – 2012-04-10 11:32:06

+0

是的!!!!!!!!!!!!!!!!!!謝謝你們倆!!!!!!!!!!!!!!!!!!!!!!!! +代表如果我能!!!!!!!!!!!!!讓我非常頭痛! – Laurence 2012-04-10 11:51:52

1

也許是這樣的:

SELECT users.*, 
     SUM(overtime_list.shift_length) AS overtime_total, 
     (SELECT GROUP_CONCAT(users_roles.short_name) 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 availability_list.type = '$type' 
    GROUP BY users.user_ID 
    ORDER BY overtime_total ASC 
+0

我得到一個錯誤「users_roles.short_name」是一個未知的列。我已經用users_roles表和角色表修改了我的原始問題以闡明。不知何故,我需要在CONCAT發生之前加入這兩張桌子......? – Laurence 2012-04-10 08:37:54

2

添加派生表,並加入回給用戶。使用派生表是因爲overtime_list上的聚合函數,因此數據不會重複。

SELECT users.*, 
    SUM(overtime_list.shift_length) AS overtime_total, 
    roles.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' 
LEFT JOIN 
(
    SELECT users_roles.user_ID, 
      GROUP_CONCAT(roles.short_name separator ', ') roles 
    from users_roles 
     INNER JOIN roles ON users_roles.role_ID = roles.role_ID 
    group by users_roles.user_ID 
) roles 
    ON users.user_ID = roles.user_ID 
WHERE availability_list.date = '$date' 
AND availability_list.type = '$type' 
GROUP BY users.user_ID 
ORDER BY overtime_total ASC 
+0

我想你錯過了subselect的from子句中的roles表。 – newenglander 2012-04-10 08:22:05

+0

@newenglander如何真實!謝謝,我糾正了我的答案。 – 2012-04-10 08:26:02

+0

沒問題。我喜歡這個查詢,因爲它可以防止選擇列表變得太長。 – newenglander 2012-04-10 08:30:24

0

我從來不喜歡使用的查詢功能,用戶數據庫引擎將作爲黑盒和着內部優化查詢,這樣就可以避免它們成爲可能。隨着跨應用你會得到相同的結果intendend:(沒有測試所有查詢作爲我沒有使用的所有對象)

SELECT users.*, 
     SUM(overtime_list.shift_length) AS overtime_total, 
     LEFT(ISNULL(roles.roles, ', '), LEN(ISNULL(roles.roles, ', ')) - 1) as roles 
    FROM availability_list 
    INNER JOIN users 
     ON users.user_ID = availability_list.user_ID 
    CROSS APPLY (
     SELECT short_name + ', ' 
     FROM roles 
     inner users_roles ON roles.role_id = users_roles.role_ID 
     WHERE users.user_ID = users_roles.user_ID 
     ORDER BY roles.role_id 
     FOR XML PATH('') 
    ) roles (roles)   
    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 availability_list.type = '$type' 
    GROUP BY users.user_ID 
    ORDER BY overtime_total ASC 
+0

GROUP_CONCAT是MySql中的內置聚合函數。 – 2012-04-10 10:35:50