我正在尝试运行查询来获取工作空闲的插槽。 ' 的SQL架构'表格如下:
+------------+----------+------------+----------+
| workID | workerID | workerType | workTime |
+------------+----------+------------+----------+
| 0000000001 | 1 | agents | 1 |
| 0000000002 | 1 | agents | 2 |
| 0000000003 | 1 | agents | 4 |
| 0000000004 | 1 | agents | 4 |
+------------+----------+------------+----------+
另一张表' 工作人员'如:
+----------+------------+
| workerID | workerName |
+----------+------------+
| 1 | John Doe |
+----------+------------+
我需要输出如下:
+------------+-----------+-----------+-----------+-----------+
| workerType | timeslot1 | timeslot2 | timeslot3 | timeslot4 |
+------------+-----------+-----------+-----------+-----------+
| John Doe | Occupied | Occupied | Free | Occupied |
+------------+-----------+-----------+-----------+-----------+
但是根据我的查询,如果我GROUP BY wo.workerID
,那么我
+------------+-----------+-----------+-----------+-----------+
| workerName | timeslot1 | timeslot2 | timeslot3 | timeslot4 |
+------------+-----------+-----------+-----------+-----------+
| John Doe | Free | Free | Free | Occupied |
+------------+-----------+-----------+-----------+-----------+
我的尝试:
SELECT wo.workerName,
CASE
WHEN w.workTime = 1 THEN 'Occupied'
ELSE 'Free'
END AS timeSlot1,
CASE
WHEN w.workTime = 2 THEN 'Occupied'
ELSE 'Free'
END AS timeSlot2,
CASE
WHEN w.workTime = 3 THEN 'Occupied'
ELSE 'Free'
END AS timeSlot3,
CASE
WHEN w.workTime = 4 THEN 'Occupied'
ELSE 'Free'
END AS timeSlot4
FROM works AS w
INNER JOIN workers AS wo ON wo.workerID = w.workerID
WHERE w.workerType = 'agents' AND
w.workerID = 1
GROUP BY wo.workerID;
答案 0 :(得分:2)
只需添加max()
旋转功能
SELECT wo.workerName,
max( CASE
WHEN w.workTime = 1 THEN 'Occupied'
ELSE 'Free'
END) AS timeSlot1,
max(CASE
WHEN w.workTime = 2 THEN 'Occupied'
ELSE 'Free'
END) AS timeSlot2,
max(CASE
WHEN w.workTime = 3 THEN 'Occupied'
ELSE 'Free'
END) AS timeSlot3,
max(CASE
WHEN w.workTime = 4 THEN 'Occupied'
ELSE 'Free'
END) AS timeSlot4
FROM works AS w
INNER JOIN workers AS wo ON wo.workerID = w.workerID
WHERE w.workerType = 'agents' AND
w.workerID = 1
答案 1 :(得分:1)
http://www.sqlfiddle.com/#!9/33230/11
SELECT wo.workerName,
IF(SUM(IF(w.workTime = 1,1,0)),'Occupied','Free') AS timeSlot1,
IF(SUM(IF(w.workTime = 2,1,0)),'Occupied','Free') AS timeSlot2,
IF(SUM(IF(w.workTime = 3,1,0)),'Occupied','Free') AS timeSlot3,
IF(SUM(IF(w.workTime = 4,1,0)),'Occupied','Free') AS timeSlot4
FROM works AS w
INNER JOIN workers AS wo ON wo.workerID = w.workerID
WHERE w.workerType = 'agents' AND
w.workerID = 1
GROUP BY w.workerID
答案 2 :(得分:1)
来自@Abhik Chakraborty
的答案可能适用于此特定情况,但如果您更改了字符串,例如,占用将变为忙碌,您将从MAX()
获得免费。
这是因为MAX()
以char-by-char为基础比较字符串。您应该分配一个整数值,然后在其上应用一个函数。
他的方法会失败:
每当Occupied
的第一个字符小于Free
字符时。例如,将Occupied
重命名为Busy
。
-- How it works right now
select greatest('occupied','free');
greatest
----------
occupied
-- How the behaviour would change if we rename occupied to free
select greatest('busy','free');
greatest
----------
free
为防止出现这种情况,使用此方法更安全:
SELECT
workerName,
CASE WHEN timeSlot1 = 1 THEN 'Occupied' ELSE 'Free' END AS timeSlot1,
CASE WHEN timeSlot2 = 1 THEN 'Occupied' ELSE 'Free' END AS timeSlot2,
CASE WHEN timeSlot3 = 1 THEN 'Occupied' ELSE 'Free' END AS timeSlot3,
CASE WHEN timeSlot4 = 1 THEN 'Occupied' ELSE 'Free' END AS timeSlot4
FROM(
SELECT
wo.workerName,
MAX(CASE WHEN w.workTime = '1' THEN 1 END) AS timeSlot1,
MAX(CASE WHEN w.workTime = '2' THEN 1 END) AS timeSlot2,
MAX(CASE WHEN w.workTime = '3' THEN 1 END) AS timeSlot3,
MAX(CASE WHEN w.workTime = '4' THEN 1 END) AS timeSlot4
FROM
works AS w
INNER JOIN workers AS wo ON wo.workerID = w.workerID
WHERE
w.workerType = 'agents' AND
w.workerID = 1
GROUP BY wo.workerName
) foo;
重要提示
您的workTime
列也不应该是varchar(n)
的类型。这很容易出错,因为它会按字符比较字符串。
select greatest('211'::varchar, '29'::varchar);
greatest
----------
29
我认为这不是你预期的结果。