Mysql 使用子查询的SQL

Mysql 使用子查询的SQL,mysql,sql,Mysql,Sql,我想为目前报名的志愿者人数低于所需数量的特定活动制作一份类似的清单。我正在使用MySQL: Volunteer Role ============== Stewarding Video 急救没有出现,因为已经有2人报名参加了这个团队 我的表格如下: Delegate ======== OrderId Name volunteerOption 1 Tim 1 Jane First Aid 1 Mary

我想为目前报名的志愿者人数低于所需数量的特定活动制作一份类似的清单。我正在使用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
我想我需要使用带有连接的子查询,但我不确定如何链接它们

我有两个疑问:

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。