2017-04-27 85 views
0

我想为特定事件生成一个类似的列表,其中当前注册的志愿者人数低于所需的数量。我使用的MySQL:使用子查询的SQL

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

是'蒂姆'的意思是'videoer'的'volunteerOption'值? – toonice

+0

每个'Event'都可以有很多'Order'吗? – toonice

+0

由于GROUP BY不返回任何重复,因此无需执行SELECT DISTINCT。 – jarlh

回答

0

这给你事项标识,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 
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 
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; 

该声明首先执行DelegateOrders之间的INNER JOIN,向我们提供了分配给每个订单的代理人列表,从而分配给每个事件。

此列表然后右键联接到VolunteerRole,给我们一个代表分配给每个事件该事件中的每个角色的代表名单。执行RIGHT JOIN而不是INNER JOIN,这样即使没有分配代理人,仍然会列出事件中的角色。请注意,RIGHT JOINLEFT JOIN大致相同。你使用的是哪一边的JOIN有哪张表保留不匹配的记录。

然后通过WHERE子句将由两个连接产生的数据集细化为eventId1的那些记录。

然后将细化的数据集按volunteerName分组。通过quantityNeeded分组不会有效地细化或扩大volunteerName的分组,因为volunteerName的每个值只有一个对应值quantityNeeded,但GROUP BY要求您使用非聚合函数生成的所有字段进行分组。

然后计算每个非NULLvolunteerOption的计数。 COUNT()将返回0其中一个角色没有分配的代表,即在那里遇到一个NULL值,而一个非NULLvolunteerOptionvolunteerName这里混淆,这将永远在每条记录的值)。

子查询然后返回一个列表,其中包含每个volunteerName及其对应的quantityNeededvolunteersCount(给予我们的计数的别名)。

然后,主要查询将子查询的数据集细化为只需要那些数量大于指定志愿者和组的结果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; 
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;