Mysql 使用子查询的SQL
我想为目前报名的志愿者人数低于所需数量的特定活动制作一份类似的清单。我正在使用MySQL:Mysql 使用子查询的SQL,mysql,sql,Mysql,Sql,我想为目前报名的志愿者人数低于所需数量的特定活动制作一份类似的清单。我正在使用MySQL: Volunteer Role ============== Stewarding Video 急救没有出现,因为已经有2人报名参加了这个团队 我的表格如下: Delegate ======== OrderId Name volunteerOption 1 Tim 1 Jane First Aid 1 Mary
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
我想我需要使用带有连接的子查询,但我不确定如何链接它们
我有两个疑问:
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
这给了我目前每个团队的志愿者数量。我不明白的是,如何只选择志愿者人数少于最大人数的团队
感谢您的任何帮助这将为您提供所需的事件id、订单id、员工类型、员工id,无论您需要什么:
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
我认为您必须分两步来完成,因为您无法将聚合值与非聚合值进行检查
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
请尝试以下方法
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;
此语句首先在委托和订单之间执行内部联接,为我们提供分配给每个订单以及每个事件的委托列表
然后,此列表将右键连接到志愿者角色,为我们提供分配给每个活动和该活动中每个角色的代表列表。执行右联接而不是内部联接,这样即使未分配代理,事件中的角色仍会列出
请注意,右连接与左连接基本相同。使用哪一个连接取决于连接的哪一侧具有应该保留不匹配记录的表
然后,通过WHERE子句将两个连接产生的数据集细化为eventId为1的记录
然后按名称对优化后的数据集进行分组。按QuantityRequired分组并不能有效地细化或扩展按志愿者名称分组,因为志愿者名称的每个值将只有一个对应的QuantityRequired值,但GROUP by要求您使用聚合函数未生成的所有字段进行分组
然后计算该选项的每个非空值的计数。COUNT将返回0,其中角色未分配任何委托,即遇到空值而不是非空值,因为此处的志愿者选项不会与志愿者名称混淆,每个记录中始终有一个值
然后,子查询返回一个列表,其中包含每个志愿者姓名及其对应的QuantityRequired,并志愿者查找给定给计数的别名
然后,主查询将子查询的数据集细化为所需数量大于分配的志愿者数量的数据集,并按志愿者姓名对结果进行分组。然后,语句将返回该组中的每个名称值
如果您有任何问题或意见,请随时发表相应的评论
附录
如果您希望扩展此语句以列出所有角色未充分填充的事件以及每个角色未充分填充的事件,您可以使用
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;
尝试此查询。这应该行得通
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;
Tim是否应该具有视频的志愿者选项值?每个事件是否可以有多个订单?无需执行SELECT DISTINCT,因为GROUP BY不会返回重复项。您的示例数据不包括视频志愿者角色中的记录。你在代理中错投了Stewarding。