此查询会生成正确的答案:
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 |
+----------+------------+
答案 0 :(得分: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
答案 1 :(得分:2)
添加派生表并将其连接回用户。由于extraime_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
答案 2 :(得分: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
答案 3 :(得分:0)
我从不喜欢在查询上使用用户函数,因为数据库引擎将函数视为黑盒并且无法在内部优化查询,因此尽可能避免使用它们。使用交叉应用你会得到与意愿相同的结果:(没有测试所有查询,因为我没有使用所有对象)
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