我想为特定活动制作一个这样的清单,目前报名的志愿者数量低于所需数量。我正在使用MySQL:
Volunteer Role
==============
Stewarding
Video
(急救没有出现,因为已经有2人签约了这个团队)
我的表格是:
Delegate
========
OrderId Name volunteerOption
1 Tim
1 Jane First Aid
1 Mary First Aid
1 Jo Stearding
VolunteerRole
===========
eventId volunteerName quantityNeeded
1 First Aid 2
1 Stewarding 10
Orders
======
Id eventId
1 1
Event
=====
id name
1 Fun Run
我认为我需要使用带有连接的子查询,但我不确定如何链接它们。
我的两个问题是:
SELECT roleName, quantity as size
FROM VolunteerRole
WHERE eventId = 1
这给了我团队名称和最大尺寸
SELECT DISTINCT count(volunteerOption) as volunteers, volunteerOption
FROM delegate
JOIN orders on delegate.orderId = orders.id
WHERE orders.eventId = 1 and volunteerOption <> ''
GROUP BY volunteerOption
这给了我每个团队目前的志愿者数量。我无法弄清楚的是如何只选择志愿者数量少于最大值的团队。
感激不尽的任何帮助
答案 0 :(得分:1)
请尝试以下方法......
SELECT volunteerName AS 'Volunteer Role'
FROM ( SELECT volunteerName AS volunteerName,
quantityNeeded AS quantityNeeded,
COUNT( volunteerOption ) AS volunteersCount
FROM Delegate
JOIN Orders ON Delegate.OrderId = Orders.Id
RIGHT JOIN VolunteerRole ON Orders.eventId = VolunteerRole.eventId
AND Delegate.volunteerOption = VolunteerRole.volunteerName
WHERE Orders.eventId = 1
GROUP BY volunteerName,
quantityNeeded
) AS volunteersCountFinder
WHERE quantityNeeded > volunteersCount
GROUP BY volunteerName;
此声明首先在INNER JOIN
和Delegate
之间执行Orders
,向我们提供分配给每个订单以及每个事件的代理列表。
然后将此列表右键加入VolunteerRole
,为我们提供分配给该事件中每个事件和的每个角色的代表列表。执行RIGHT JOIN
而不是INNER JOIN
,以便即使没有分配代理,仍会列出事件中的角色。
请注意,RIGHT JOIN
与LEFT JOIN
大致相同。您使用的是由JOIN
的哪一侧具有应保留不匹配记录的表格。
然后,通过eventId
子句将两个联接生成的数据集细化为1
WHERE
的记录。
然后,精炼数据集按volunteerName
分组。按quantityNeeded
进行分组不能有效地优化或扩大volunteerName
分组,因为volunteerName
的每个值只有quantityNeeded
的一个对应值,但GROUP BY
要求您可以使用聚合函数未生成的所有字段进行分组。
然后计算NULL
的每个非volunteerOption
值的计数。 COUNT()
将返回0
,其中角色未分配任何代理,即NULL
值遇到NULL
而非volunteerOption
的值volunteerName
( 在这里与volunteerName
混淆,每个记录中都会有一个值。
子查询然后返回一个列表,其中包含每个quantityNeeded
及其对应的volunteersCount
和volunteerName
(给予我们计数的别名)。
主查询然后将子查询的数据集精确到那些所需数量大于分配的志愿者数量的数据集,并将结果按volunteerName
进行分组。然后,语句将返回此组中SELECT eventId,
volunteerName AS 'Volunteer Role'
FROM ( SELECT Orders.eventId AS eventId,
volunteerName AS volunteerName,
quantityNeeded AS quantityNeeded,
COUNT( volunteerOption ) AS volunteersCount
FROM Delegate
JOIN Orders ON Delegate.OrderId = Orders.Id
RIGHT JOIN VolunteerRole ON Orders.eventId = VolunteerRole.eventId
AND Delegate.volunteerOption = VolunteerRole.volunteerName
GROUP BY Orders.eventId,
volunteerName,
quantityNeeded
) AS volunteersCountFinder
WHERE quantityNeeded > volunteersCount
GROUP BY eventId,
volunteerName;
的每个值。
如果您有任何问题或意见,请随时发表评论。
附录
如果您希望扩展此声明以列出所有角色填充不充分的事件以及每个未充分填充的角色,您可以使用...
while
答案 1 :(得分:0)
这可以在任何需要的地方为您提供event_id,order_id,employee_type,employee_needed:
SELECT a.id as event_id, b.id as order_id, d.volunteerOption, c.quantityNeeded-d.employeed as still_to_find
FROM events a
LEFT JOIN orders b ON a.id=b.eventId
LEFT JOIN VolunteerRole c ON a.id=c.eventId
LEFT JOIN (SELECT order_id, volunteerOption, COUNT(*) as employeed FROM Delegate WHERE volunteerOption IS NOT NULL GROUP BY order_id, volunteerOption) d ON b.id=d.order_id AND c.volunteerName=d.volunteerOption
WHERE c.quantityNeeded<d.employeed
答案 2 :(得分:0)
我认为您必须分两步执行此操作,因为您无法检查聚合值与非聚合值
select distinct volunteerName
from (
SELECT t1.volunteerName, t1.quantityNeeded, count(t2.Name) as cnt
FROM VolunteerRole t1
JOIN Orders t2
ON t1.eventId = t2.eventId
LEFT JOIN
Delegate t3
ON t1.VolunteerName = t3.volunteerOption and
t2.Id = t3.OrderId
WHERE t1.eventId = 1
) t1
where quantityNeeded > cnt
答案 3 :(得分:0)
尝试此查询。这应该可以正常工作
select distinct volunteerName from (SELECT t1.volunteerName, t1.quantityNeeded, count(t2.Name) as cnt FROM VolunteerRole t1 JOIN Orders t2 ON t1.eventId = t2.eventId
LEFT JOIN Delegate t3 ON t1.VolunteerName = t3.volunteerOption and t2.Id = t3.OrderId WHERE t1.eventId = 1
) t1 where quantityNeeded > cnt;