医生多维度条件查询函数

USE [DoctorInfo]
GO
/****** Object:  UserDefinedFunction [dbo].[DoctorMultiQuery]    Script Date: 12/12/2015 20:36:41 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[DoctorMultiQuery](
    @splitstring NVARCHAR(4000),
    @querystring NVARCHAR(4000)
)
RETURNS int
AS
BEGIN
 DECLARE @result  INT,@index1 INT, @index2 INT ,@sourcestring nvarchar(9),@valuestring nvarchar(9)
 SET @result=0
 IF(charindex(',',@splitstring)=0)
    BEGIN
        SET @sourcestring=@splitstring    
        IF(charindex(',',@querystring)=0)
            BEGIN
                IF(@splitstring=@querystring)
                    BEGIN
                        SET @result=1
                    END
            END        
        ELSE
            BEGIN
                 while(charindex(',',@querystring)<>0)
                    BEGIN
                        --第一个','之前的字符串
                        SET @index2=charindex(',',@querystring)
                        SET @valuestring=substring(@querystring,1,@index2-1)        
                        IF(@sourcestring=@valuestring)
                            BEGIN
                             SET @result=1
                             BREAK
                            END
                        ELSE
                            BEGIN
                                 --将第一个','后面的字符串重新赋给@ids
                                   set @querystring=stuff(@querystring,1,@index2,'')
                                   --最后一个字符串
                                  if(charindex(',',@querystring)=0)
                                   begin
                                      IF(@sourcestring=@querystring)
                                        BEGIN
                                         SET @result=1
                                        END
                                   END
                            END
                    END
            END
    END
else
    begin
          while(charindex(',',@splitstring)<>0)
          begin
           --第一个','之前的字符串
           SET @index1=charindex(',',@splitstring)
           SET @sourcestring=substring(@splitstring,1,@index1-1)
                IF(charindex(',',@querystring)=0)
                    BEGIN
                        IF(@sourcestring=@querystring)
                            BEGIN
                                SET @result=1
                                BREAK
                            END
                    END
                ELSE
                    BEGIN
                       while(charindex(',',@querystring)<>0)
                            BEGIN
                                --第一个','之前的字符串
                                SET @index2=charindex(',',@querystring)
                                SET @valuestring=substring(@querystring,1,@index2-1)    
                                IF(@sourcestring=@valuestring)
                                    BEGIN
                                     SET @result=1
                                     BREAK
                                    END
                                ELSE
                                    BEGIN
                                         --将第一个','后面的字符串重新赋给@ids
                                           set @querystring=stuff(@querystring,1,@index2,'')
                                           --最后一个字符串
                                          if(charindex(',',@querystring)=0)
                                           begin
                                              IF(@sourcestring=@querystring)
                                                BEGIN
                                                 SET @result=1
                                                END
                                           END
                                    END
                            END
                        END
                        
            IF(@result=1)
                BEGIN
                    BREAK;
                END
            ELSE
                BEGIN
                   --将第一个','后面的字符串重新赋给@ids
                   set @splitstring=stuff(@splitstring,1,@index1,'')
                   
                   --最后一个字符串
                  if(charindex(',',@splitstring)=0)
                   begin
                      SET @sourcestring=@splitstring
                    IF(charindex(',',@querystring)=0)
                        BEGIN
                            IF(@sourcestring=@querystring)
                                begin
                                    SET @result=1
                                END
                        END
                    ELSE
                        begin
                            while(charindex(',',@querystring)<>0)
                            BEGIN
                                --第一个','之前的字符串
                                SET @index2=charindex(',',@querystring)
                                SET @valuestring=substring(@querystring,1,@index2-1)            
                                IF(@sourcestring=@valuestring)
                                    BEGIN
                                     SET @result=1
                                     BREAK
                                    END
                                ELSE
                                    BEGIN
                                         --将第一个','后面的字符串重新赋给@ids
                                           set @querystring=stuff(@querystring,1,@index2,'')
                                           --最后一个字符串
                                          if(charindex(',',@querystring)=0)
                                           begin
                                              IF(@sourcestring=@querystring)
                                                BEGIN
                                                 SET @result=1
                                                END
                                           END
                                    END
                                END
                        END
                   END
            END
          END
END
    return @result
END

转载于:https://www.cnblogs.com/chenjt/p/5041795.html

<think>好的,用户现在想查询数据库中平均每个医生的接诊次数。首先,我需要回顾之前的对话,确保这次回答符合用户的需求。之前用户问的是如何在MySQL中用患者姓名替代ID显示,我给出了几种JOIN的方法,包括关联医生表的例子。现在用户的问题是关于统计平均接诊次数,需要结合之前的表结构。 首先,要确定表结构是否已经包含医生信息。根据之前的回答,用户有创建doctors表和visits表,其中visits表包含doctor_id作为外键。所以,医生接诊记录应该存储在visits表中,每个visit对应一个doctor_id。 接下来,用户需要的是平均每个医生的接诊次数。这里需要计算所有医生的接诊次数总和,然后除以医生的数量。或者可能是每个医生的平均接诊次数,即每个医生的接诊次数的平均值。这里需要明确用户的需求。通常,平均每个医生的接诊次数可能指的是所有医生的平均,所以需要先统计每个医生的接诊次数,然后求平均值。 需要用到GROUP BY doctor_id来统计每个医生的接诊次数,然后使用AVG函数计算平均值。同时,可能需要使用子查询或者直接使用聚合函数。 另外,用户可能需要显示医生的姓名而不是ID,所以需要JOIN doctors表来获取医生姓名。之前的回答中已经涉及到了JOIN的使用,所以这里应该沿用相同的方法。 还要考虑是否有重复的医生记录或者未关联的医生,是否需要排除没有接诊记录的医生。根据用户的问题,可能只需要统计有接诊记录的医生,所以使用INNER JOIN即可。但如果有医生没有接诊记录,而用户希望包括他们,可能需要LEFT JOIN,并将接诊次数设为0,但平均的时候可能会影响结果。需要根据实际场景判断。 此外,性能方面,如果数据量大,visits表的doctor_id是否有索引?之前的优化建议提到过在visits表的patient_id上建立索引,但可能也需要在doctor_id上建立索引来加速查询。 现在,构建查询语句。首先统计每个医生的接诊次数: SELECT doctor_id, COUNT(*) AS visit_count FROM visits GROUP BY doctor_id; 然后计算平均值: SELECT AVG(visit_count) AS average_visits FROM ( SELECT doctor_id, COUNT(*) AS visit_count FROM visits GROUP BY doctor_id ) AS subquery; 如果需要同时显示医生姓名,可以在子查询里JOIN doctors表: SELECT d.doctor_name, COUNT(v.visit_id) AS visit_count FROM visits v JOIN doctors d ON v.doctor_id = d.doctor_id GROUP BY d.doctor_id; 然后计算这些visit_count的平均值: SELECT AVG(visit_count) AS average_visits FROM ( SELECT d.doctor_id, COUNT(v.visit_id) AS visit_count FROM visits v JOIN doctors d ON v.doctor_id = d.doctor_id GROUP BY d.doctor_id ) AS subquery; 或者,可以合并成一步,使用子查询在同一个语句中。另外,用户可能需要直接显示每位医生的接诊次数和整体平均,但根据问题描述,用户需要的是平均每个医生的接诊次数,所以应该返回一个单一的平均值。 此外,需要注意是否有医生没有接诊记录,这时候如果使用INNER JOIN,这些医生不会被计入,但如果用户希望包括所有医生,即使他们没有接诊,那么应该使用LEFT JOIN,并将COUNT替换为COUNT(v.visit_id),这样没有接诊记录的医生会显示为0,从而影响平均值。 但根据常见情况,可能用户只需要有接诊记录的医生的平均次数,所以使用INNER JOIN是合适的。 最后,是否需要四舍五入或者格式化输出?比如保留两位小数,可以使用ROUND函数。 另外,可能需要验证示例数据,确保查询结果的正确性。例如,如果有两位医生,分别有4次和6次接诊,那么平均是5次。测试用例可以验证这一点。 总结步骤: 1. 使用JOIN关联visits和doctors表,按医生分组统计接诊次数。 2. 使用子查询计算这些次数的平均值。 3. 格式化输出结果,可能包括医生姓名和平均次数。 现在,根据这些思考过程,构建回答,确保语法正确,使用中文,引用之前的示例结构,并生成相关问题。</think>### 分步解决方案:查询平均每位医生的接诊次数 --- #### **步骤1:确认表结构与关系** 基于引用[1]中的表结构扩展: ```sql -- 医生表 CREATE TABLE doctors ( doctor_id INT PRIMARY KEY, doctor_name VARCHAR(50) ); -- 就诊记录表(包含医生ID) CREATE TABLE visits ( visit_id INT PRIMARY KEY, doctor_id INT, -- 外键关联医生表 visit_date DATE, FOREIGN KEY (doctor_id) REFERENCES doctors(doctor_id) ); ``` --- #### **步骤2:基础统计查询** **目标**:统计每位医生的接诊次数 **方法**: 1. 使用 `JOIN` 关联 `doctors` 和 `visits` 表 2. 通过 `GROUP BY` 按医生分组 3. 用 `COUNT()` 计算接诊次数 ```sql SELECT d.doctor_name AS 医生姓名, COUNT(v.visit_id) AS 接诊次数 FROM doctors d JOIN visits v ON d.doctor_id = v.doctor_id GROUP BY d.doctor_id; ``` **输出示例**: ``` +--------------+--------------+ | 医生姓名 | 接诊次数 | +--------------+--------------+ | 王医生 | 12 | | 李医生 | 8 | | 张医生 | 15 | +--------------+--------------+ ``` --- #### **步骤3:计算全局平均值** **目标**:计算所有医生的平均接诊次数 **方法**: 1. 将步骤2的查询结果作为子查询 2. 使用 `AVG()` 函数计算平均值 ```sql SELECT AVG(接诊次数) AS 平均接诊次数 FROM ( SELECT COUNT(v.visit_id) AS 接诊次数 FROM doctors d JOIN visits v ON d.doctor_id = v.doctor_id GROUP BY d.doctor_id ) AS subquery; ``` **输出示例**: ``` +------------------+ | 平均接诊次数 | +------------------+ | 11.6667 | +------------------+ ``` --- #### **步骤4:优化显示(四舍五入+别名)** **改进点**: - 使用 `ROUND()` 保留两位小数 - 添加中文别名 ```sql SELECT ROUND(AVG(接诊次数), 2) AS 平均接诊次数 FROM ( SELECT COUNT(v.visit_id) AS 接诊次数 FROM doctors d JOIN visits v ON d.doctor_id = v.doctor_id GROUP BY d.doctor_id ) AS subquery; ``` **输出示例**: ``` +------------------+ | 平均接诊次数 | +------------------+ | 11.67 | +------------------+ ``` --- ### 关键语法解析 | 语法 | 作用 | 适用场景 | |---------------------|----------------------------------------------------------------------|-------------------| | `JOIN ... ON` | 关联医生表和就诊记录表 | 多表数据匹配 | | `GROUP BY` | 按医生分组统计 | 聚合计算 | | `COUNT()` | 统计每个医生的就诊记录数量 | 计数操作 | | `AVG()` | 计算平均值 | 全局统计分析 | | `ROUND()` | 控制小数精度 | 数据可视化优化 | --- ### 性能优化建议 1. **索引优化**: 在 `visits.doctor_id` 上添加索引,加速分组查询(引用[1]中提到的索引优化原则): ```sql CREATE INDEX idx_doctor_id ON visits(doctor_id); ``` 2. **过滤无效数据**: 添加 `WHERE` 条件排除无效记录(如空医生ID): ```sql SELECT COUNT(v.visit_id) AS 接诊次数 FROM doctors d JOIN visits v ON d.doctor_id = v.doctor_id WHERE v.doctor_id IS NOT NULL -- 过滤空值 GROUP BY d.doctor_id; ``` --- ### 扩展应用示例 **统计科室维度下的医生平均接诊次数**(需关联科室表): ```sql SELECT dept.dept_name AS 科室名称, ROUND(AVG(sub.接诊次数), 2) AS 科室医生平均接诊次数 FROM ( SELECT d.doctor_id, d.dept_id, -- 假设医生表新增科室ID字段 COUNT(v.visit_id) AS 接诊次数 FROM doctors d JOIN visits v ON d.doctor_id = v.doctor_id GROUP BY d.doctor_id ) AS sub JOIN departments dept ON sub.dept_id = dept.dept_id -- 关联科室表 GROUP BY dept.dept_name; ``` --- ### 相关问题 1. 如何查询接诊次数最多的前3名医生? 2. 如何统计每天的平均接诊量? 3. 如果存在未关联医生的就诊记录,如何计算包含这些记录的全局平均值?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值