sql—添加的实际记录数

sql—添加的实际记录数,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,我试图根据咨询和实际情况生成一份报告,看看有多少咨询转化为实际情况 我有一张桌子,上面有病人、预约类别、医生、预约 以下是业务规则 如果患者在咨询后进行了预约,则获取所有预约 用户可以先进行咨询预订,然后预订属于同一咨询组的一个或多个预订。示例:他们可以先预订牙科咨询,然后再预订与该组对应的任何内容。我e牙科手术和牙齿修复。这些信息保存在咨询xActualBookingCategoryMap表中 如果患者预订多于一个,实际预订只考虑一个,未取消 如果取消咨询,不要考虑。 如果实际取消,不要考

我试图根据咨询和实际情况生成一份报告,看看有多少咨询转化为实际情况

我有一张桌子,上面有病人、预约类别、医生、预约

以下是业务规则

  • 如果患者在咨询后进行了预约,则获取所有预约
  • 用户可以先进行咨询预订,然后预订属于同一咨询组的一个或多个预订。示例:他们可以先预订
    牙科咨询
    ,然后再预订与该组对应的任何内容。我e牙科手术和牙齿修复。这些信息保存在
    咨询xActualBookingCategoryMap
    表中
  • 如果患者预订多于一个,实际预订只考虑一个,未取消
  • 如果取消咨询,不要考虑。 如果实际取消,不要考虑。
  • 获取咨询预约总数(不需要是实际预约医生)和每个医生的实际预约。任何人都可以成为咨询医生。但报告中我们只考虑了真正的
  • 的医生。 这是我尝试过的SQL。但它会记录所有记录,而不是该组的一个实际记录

    SELECT  P.Name As Patient, SurgeryB.BookingId, SurgeryB.BookingDate, C.CategoryName, 
    d.name as doctor
    FROM BOOKING CounsB
    INNER JOIN BOOKING SurgeryB 
      ON CounsB.PatientId = SurgeryB.PatientId AND ISNULL(SurgeryB.IsCancelled,0)=0
    INNER JOIN CounselingXActualBookingCategoryMap MAP 
      ON MAP.CounselingCategoryId = CounsB.CategoryId 
         AND MAP.ActualBookingCategoryId = SurgeryB.CategoryId  
         AND SurgeryB.BookingDate > CounsB.BookingDate
     INNER JOIN PATIENT P ON P.PATIENTID = SurgeryB.PATIENTID
     inner join category c on c.categoryid= SurgeryB.CategoryId
     inner join doctor d on SurgeryB.doctorid = d.doctorid
     WHERE ISNULL(CounsB.IsCancelled,0)=0
     order by p.patientid
    
    问题:

  • 我不想看到Alex为牙齿修复预订的记录,因为他已经为同一组牙科和分类
    牙科手术实际预订了牙齿修复

  • 我想得到咨询和实际预约。示例100提供咨询服务,每个咨询类别仅实际预订了70次。

    我在您的代码中添加了以下内容:

    SELECT  P.Name As Patient, SurgeryB.BookingId, SurgeryB.BookingDate, C.CategoryName, map.GroupId, map.CounselingCategoryId, map.ActualBookingCategoryId,
    d.name as doctor
    into #temp
    FROM BOOKING CounsB
    INNER JOIN BOOKING SurgeryB 
      ON CounsB.PatientId = SurgeryB.PatientId AND ISNULL(SurgeryB.IsCancelled,0)=0
    INNER JOIN CounselingXActualBookingCategoryMap MAP 
      ON MAP.CounselingCategoryId = CounsB.CategoryId 
         AND MAP.ActualBookingCategoryId = SurgeryB.CategoryId  
         AND SurgeryB.BookingDate > CounsB.BookingDate
     INNER JOIN PATIENT P ON P.PATIENTID = SurgeryB.PATIENTID
     inner join category c on c.categoryid= SurgeryB.CategoryId
     inner join doctor d on SurgeryB.doctorid = d.doctorid
     WHERE ISNULL(CounsB.IsCancelled,0)=0
     order by p.patientid
    
    ;with cte as 
    (   
        select Patient, BookingId, BookingDate, CategoryName, Doctor, ROW_NUMBER() over (partition by Patient, GroupId order by BookingDate) row_num 
        from #temp t
    )
    select Patient, BookingId, BookingDate, CategoryName, Doctor from cte where row_num = 1
    
    drop table #temp
    

    对于您作为示例给出的查询,我有一个答案,在业务规则1和业务规则6中都有描述

    我对您的表做了一些轻微的更改,因为我必须重新创建它们来测试查询

    create table patient
    (
      id                     int,
      name                   varchar(8)
    );
    
    create table doctor
    (
      id                     int,
      name                   varchar(8)
    );
    
    create table category
    (
      id                     int,
      name                   varchar(20),
      counseling_or_surgery  varchar(10)
    );
    
    create table map
    (
      counseling_category_id   int,
      surgery_category_id      int,
      group_id                 int
    );
    
    create table booking
    (
      id                       int,
      patient_id               int,
      category_id              int,
      doctor_id                int,
      booking_date             date,
      cancelled                bit
    );
    
    以下是设置数据的插入:

    insert into patient (id, name) values (1, 'Alex');
    insert into patient (id, name) values (2, 'John');
    insert into patient (id, name) values (3, 'Mark');
    insert into patient (id, name) values (4, 'Stephen');
    
    insert into doctor (id, name) values (1, 'Doctor 1');
    insert into doctor (id, name) values (2, 'Doctor 2');
    insert into doctor (id, name) values (3, 'Doctor 3');
    
    insert into category (id, name, counseling_or_surgery) values (1, 'Counseling Dental', 'Counseling');
    insert into category (id, name, counseling_or_surgery) values (2, 'Counseling Nose',   'Counseling');
    insert into category (id, name, counseling_or_surgery) values (3, 'Dental surgery',    'Surgery');
    insert into category (id, name, counseling_or_surgery) values (4, 'Teeth repair',      'Surgery');
    insert into category (id, name, counseling_or_surgery) values (5, 'Nose Surgery',      'Surgery');
    insert into category (id, name, counseling_or_surgery) values (6, 'Nose adjustment',   'Surgery');
    
    insert into map (counseling_category_id, surgery_category_id, group_id) values (1, 3, 1);
    insert into map (counseling_category_id, surgery_category_id, group_id) values (1, 4, 1);
    insert into map (counseling_category_id, surgery_category_id, group_id) values (2, 5, 2);
    insert into map (counseling_category_id, surgery_category_id, group_id) values (2, 6, 2);
    
    insert into booking (id, patient_id, category_id, doctor_id, booking_date, cancelled) values ( 1, 1, 1, 1, '2017-11-20', 'false');
    insert into booking (id, patient_id, category_id, doctor_id, booking_date, cancelled) values ( 2, 1, 3, 3, '2017-11-25', 'false');
    insert into booking (id, patient_id, category_id, doctor_id, booking_date, cancelled) values ( 3, 1, 4, 2, '2017-11-25', 'false');
    insert into booking (id, patient_id, category_id, doctor_id, booking_date, cancelled) values ( 4, 1, 2, 1, '2017-11-21', 'true');
    insert into booking (id, patient_id, category_id, doctor_id, booking_date, cancelled) values ( 5, 1, 2, 2, '2017-11-26', 'false');
    insert into booking (id, patient_id, category_id, doctor_id, booking_date, cancelled) values ( 6, 1, 5, 3, '2017-11-28', 'false');
    insert into booking (id, patient_id, category_id, doctor_id, booking_date, cancelled) values ( 7, 3, 2, 2, '2017-11-26', 'false');
    insert into booking (id, patient_id, category_id, doctor_id, booking_date, cancelled) values ( 8, 3, 6, 2, '2017-11-26', 'true');
    insert into booking (id, patient_id, category_id, doctor_id, booking_date, cancelled) values ( 9, 4, 2, 2, '2017-11-29', 'false');
    insert into booking (id, patient_id, category_id, doctor_id, booking_date, cancelled) values (10, 4, 5, 1, '2017-11-29', 'false');
    
    给定这些表,下面是对业务规则1的查询:

    select
        c.name          as patient,
        b.id            as booking_id,
        b.booking_date  as first_surgery_date,
        d.name          as first_surgery,
        e.name          as doctor
    from
        (
            select
                r.patient_id,
                min(r.id)           as booking_id,
                t.group_id
            from
                booking r
                join
                category s
                on r.category_id = s.id
                join
                map t
                on t.surgery_category_id = r.category_id
            where
                r.cancelled = 0 and
                s.counseling_or_surgery = 'Surgery'
            group by
                r.patient_id,
                t.group_id
        ) a
        join
        booking b
        on a.booking_id = b.id
        join
        patient c
        on b.patient_id = c.id
        join 
        category d
        on b.category_id = d.id
        join
        doctor e
        on b.doctor_id = e.id;
    
    结果是:

    patient          booking_id  first_surgery_date first_surgery    doctor
    ---------------- ----------- ------------------ ---------------- ----------------
    Stephen                   10         2017-11-29 Nose Surgery     Doctor 1
    Alex                       2         2017-11-25 Dental surgery   Doctor 3
    Alex                       6         2017-11-28 Nose Surgery     Doctor 3
    
    (3 rows affected)
    
    这里是对业务规则6的查询。取消也算在内;如果这不是你想要的,很容易改变

    select
        z.name                     as doctor,
        y.total_counseling_bookings,
        x.total_surgery_bookings
    from
        (
            select
                doctor_id,
                count(*) as total_surgery_bookings
            from
                booking a
                join
                category b
                on a.category_id = b.id
            where
                b.counseling_or_surgery = 'Surgery'
            group by 
                doctor_id
        ) x
        full outer join
        (
            select
                doctor_id,
                count(*) as total_counseling_bookings
            from
                booking c
                join
                category d
                on c.category_id = d.id
            where
                d.counseling_or_surgery = 'Counseling'
            group by 
                doctor_id
        ) y
        on x.doctor_id = y.doctor_id
        join
        doctor z
        on x.doctor_id = z.id
    
    下面是这一次的结果:

    doctor   total_counseling_bookings total_surgery_bookings
    -------- ------------------------- ----------------------
    Doctor 1                         2                      1
    Doctor 2                         3                      2
    Doctor 3                      NULL                      2
    
    (3 rows affected)
    

    对于给定的数据,预期输出是什么?@mxix我更新了问题。请阅读最后一点粗体字