简体   繁体   English

SQL 列出在另一个表中出现少于 N 次的项目

[英]SQL List items that appears less than N times in another table

Here is my database model.这是我的数据库 model。

class Doctor(db.Model):
    __tablename__ = 'doctor'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(120), nullable=False)

class Patient(db.Model):
    __tablename__ = 'patient'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(120), nullable=False)

class Assignment(db.Model):
    __tablename__ = 'assignment'
    doctorid = db.Column(db.Integer, ForeignKey('doctor.id'),
                        unique=False, nullable=False, index=True, primary_key=True)
    patientid = db.Column(db.Integer, ForeignKey('patient.id'),
                       unique=False, nullable=False, index=True, primary_key=True)
    created = db.Column(db.DateTime(timezone=False),
                        server_default=db.func.now())

I would like to list all Doctors who has less than 3 (may be a user-specified N ) Patients assigned.我想列出分配了少于 3 名(可能是用户指定的N )患者的所有医生。 The assignment is recorded in the assignment table using ForeignKey.使用 ForeignKey 将分配记录在assignment表中。

Note that some Doctors may have zero Patient assigned, they should also be included in the results.请注意,某些医生可能分配了零个患者,他们也应该包含在结果中。

I was thinking about something like sub-queries, GROUP BY or OUTER JOIN but I couldn't figure out how to put counting N in them.我在考虑诸如子查询、GROUP BY 或 OUTER JOIN 之类的东西,但我不知道如何将N数放入其中。

Also, I would like to further exclude all Doctors who are assigned with a certain Patient patientid = P1 from the results.另外,我想从结果中进一步排除所有分配有某个 Patient patientid = P1的医生。 Is this possible to be done in addition to the first (less then N ) condition?除了第一个(小于N )条件之外,是否可以这样做?

To count the number of assignments per doctor use GROUP BY and to select only groups, in this case doctors, meeting certain criteria use the HAVING clause.要计算每个医生的分配数量,请使用 GROUP BY 和 select 仅组,在这种情况下,满足某些标准的医生使用 HAVING 子句。 It is possible to deterministically select non aggregate columns from a group, if they are functionally dependent on the grouping, which is the case if grouping by primary key.如果它们在功能上依赖于分组,则可以确定性地从组中确定 select 非聚合列,如果按主键分组就是这种情况。

docs = db.session.query(Doctor).\
    outerjoin(Assignment).\
    group_by(Doctor.id).\
    having(
        db.func.count() < n,
        db.func.count().filter(Assignment.patientid == p1) == 0).\
    all()

If your DBMS does not support the aggregate FILTER clause used above to eliminate doctors assigned with patient P1, you can use an EXISTS subquery expression instead:如果您的 DBMS 不支持上述用于消除分配给患者 P1 的医生的聚合 FILTER 子句,则可以改用 EXISTS 子查询表达式:

docs = db.session.query(Doctor).\
    outerjoin(Assignment).\
    filter(db.not_(db.session.query(Assignment).filter(
        Assignment.patientid == p1,
        Assignment.doctorid == Doctor.id).exists())).\
    group_by(Doctor.id).\
    having(db.func.count() < n).\
    all()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM