MySQL:计算多对多和一对多(以及其他东西)

时间:2017-11-27 03:35:31

标签: mysql join group-by many-to-many one-to-many

我有一个包含许多表的MySQL数据库。与此问题相关的是:

TABLE: Schedule (For booking time on a machine)
       - SlotID (INTEGER - AUTO_INCREMENT - PRIMARY KEY)
       - SlotDate (VARCHAR)
       - SlotStart (INTEGER)
       - SlotStop (INTEGER)
       - UserID (INTEGER - FOREIGN KEY REFERENCES User.UserID)
       - OperatorID (INTEGER - FOREIGN KEY REFERENCES User.UserID)

TABLE: Treatment (Defines what the machine should do)
       - TreatmentID (INTEGER - AUTO_INCREMENT - PRIMARY KEY)
       - SOME OTHER BOOLEANS TO ACTIVATE EACH SENSOR (Irrelevant)

TABLE: ScheduleTreatment (Many to many relationships between Schedule & Treatment)
       - SlotID (INTEGER - FOREIGN KEY REFERENCES Schedule.SlotID)
       - TreatmentID (INTEGER - FOREIGN KEY REFERENCES Treatment.TreatmentID)

TABLE: Individual (each treatment will be applied to n different individuals)
       - IndID (INTEGER - AUTO_INCREMENT - PRIMARY KEY)
       - Active (BOOLEAN if 0 this should be ignored and not counted)
       - TreatmentID (INTEGER - FOREIGN KEY REFERENCES Treatment.TreatmentID)

TABLE: User (Table with user data)
       - UserID (INTEGER - AUTO_INCREMENT - PRIMARY KEY)
       - Username (VARCHAR)
       - Some other irrelevant fields

所以保留的机器插槽放在Schedule上,要执行的操作放在Treatment上,执行这些操作的个人(每个处理都在许多相同的人身上进行统计)将IndividualScheduleTreatment链接到该插槽中应该进行的不同处理(并且可以使用TreatmentID foreing key获取可以执行此操作的个人。 OperatorID提供指向用户(不是广告位所有者)的链接,该用户将负责忽略该过程。

我想执行插槽预览,以便用户可以查看所有信息(因此查询应以WHERE Schedule.UserID = ?结尾),这意味着获取Schedule.*,操作员的用户名和两个计数:有多少种治疗方法(这一种方法相对简单,ScheduleTreatmentGROUP BY),另外一种方法(在所有指定的治疗方法中),我绝对不知道怎么做。没有治疗的槽或带治疗的槽也不应该出现(在相应的计数中为0)。

在我看来,这需要按两个不同的标准进行分组,但它也可以在一个(比我聪明)查询中完成。我已经设法单独完成它们,但不是在同一个查询中。以下是获取Treatment.*以及分配给它的所有个人的示例:

SELECT Treatment.TreatmentID, COUNT(Individual.TreatmentID) AS Individuals
FROM Treatment INNER JOIN Individual ON Individual.TreatmentID = 
Treatment.TreatmentID GROUP BY Individual.TreatmentID ORDER BY TreatmentID

提前致谢,

1 个答案:

答案 0 :(得分:0)

我想执行Slot预览,以便用户可以看到所有信息(因此查询应以WHERE Schedule.UserID =?结尾),这意味着获取Schedule。*

select Schedule.* from Schedule WHERE Schedule.UserID = ?

,运营商的用户名,

select Schedule.*, op.username as OperatorName 
from Schedule s
inner join User op on s.OperatorID = op.id
where Schedule.UserID = ?

和两个计数:一个治疗次数(这个治疗相对简单,使用ScheduleTreatment和GROUP BY)

SELECT SlotID, COUNT(*) scount
FROM ScheduleTreatment
GROUP BY SlotID

和另外一个人(在所有指定的治疗中)和我在这里完全不知道如何。

SELECT SlotID, COUNT(*) icount
FROM ScheduleTreatment st
INNER JOIN Individual i on st.TreatmentID = i.TreatmentID 
WHERE i.actve <> 0
GROUP BY SlotID

没有治疗的老虎机或带治疗的老虎机也不应该出现(在相应的计数中为0)。

SELECT Schedule.*, op.username as OperatorName , st.scount, i.icount
FROM Schedule s
INNER JOIN User op on s.OperatorID = op.id
LEFT JOIN (
           SELECT SlotID, COUNT(*) scount
           FROM ScheduleTreatment
           GROUP BY SlotID
           ) st on s.slotid = st.slotid
LEFT JOIN (
           SELECT SlotID, COUNT(*) icount
           FROM ScheduleTreatment st
           INNER JOIN Individual i on st.TreatmentID = i.TreatmentID 
           WHERE i.actve <> 0
           GROUP BY SlotID
           ) i on s.slotid = i.slotid
WHERE Schedule.UserID = ?